# Commons $G$ = [ED25519](https://ed25519.cr.yp.to/) base point $(x, -4/5)$ $H(x)$ = keccak-256 via `cn_fast_hash()` $sc(x)$ = sc_reduce32(x) $H_p(x)$ = hash_to_ec(x) $H_s(x) = sc(H(x))$ $||$ = concatenation <sup>s</sup> denotes a scalar # Normal Wallet ## Address Generation $b$ = random private spend key $B$ = public spend key $a$ = private view key $A$ = public view key $B = bG$ $a = H_s(b)$ $A = aG$ # Multisig Wallets <details> <summary>N:N (2/2 Example) Generation</summary> ### Party 1 $b_0$ = random private spend key $B_0 = bG$ $a_0 = H_s(b_0)$ $A_0 = aG$ ### Party 2 $b_1$ = random private spend key $B_1 = bG$ $a_1 = H_s(b_1)$ $A_1 = aG$ ### Multisig Wallet Exchange the `a` and `B` keys with everyone in the group. $b$ = unknown to all $B = B_0 + B_1$ $a = a_0 + a_1$ $A = aG$ </details> <details> <summary>N-1:N (2/3 Example) Generation</summary> ### Party 1 $b_0$ = random private spend key $B_0 = bG$ $a_0 = H_s(b_0)$ $A_0 = aG$ ### Party 2 $b_1$ = random private spend key $B_1 = bG$ $a_1 = H_s(b_1)$ $A_1 = aG$ ### Party 3 $b_2$ = random private spend key $B_2 = bG$ $a_2 = H_s(b_2)$ $A_2 = aG$ ### Multisig Wallet #### Step 1 Exchange the `a` and `B` keys with everyone in the group. ##### Party 1 $m_1 = H_s(b_0B_1)$ $M_1 = m_1G$ $m_2 = H_s(b_0B_2)$ $M_2 = m_2G$ ##### Party 2 $m_3 = H_s(b_1B_0)$ $M_3 = m_3G$ $m_4 = H_s(b_1B_2)$ $M_4 = m_4G$ ##### Party 3 $m_5 = H_s(b_2B_0)$ $M_5 = m_5G$ $m_6 = H_s(b_2B_1)$ $M_6 = m_6G$ #### Step 2 Exchange the `M` keys with everyone in the group. **Note:** Only the unique `M` keys are used to calculate $B$. $H_s(b_0B_1) == H_s(b_1B_0) == M_1 == M_3$ $H_s(b_0B_2) == H_s(b_2B_0) == M_2 == M_5$ $H_s(b_1B_2) == H_s(b_2B_1) == M_4 == M_6$ #### Step 3 $b$ = unknown to all $B = H_s(b_0B_1)G + H_s(b_0B_2)G + H_s(b_1B_2)G$ $B = M_1 + M_2 + M_4$ $a = a_0 + a_1 + a_2$ $A = aG$ </details> <details> <summary>N:M (2/4 Example) Generation</summary> ### Party 1 $b_0$ = random private spend key $B_0 = bG$ $a_0 = H_s(b_0)$ $A_0 = aG$ ### Party 2 $b_1$ = random private spend key $B_1 = bG$ $a_1 = H_s(b_1)$ $A_1 = aG$ ### Party 3 $b_2$ = random private spend key $B_2 = bG$ $a_2 = H_s(b_2)$ $A_2 = aG$ ### Party 4 $b_3$ = random private spend key $B_3 = bG$ $a_3 = H_s(b_3)$ $A_3 = aG$ ### Multisig Wallet #### Step 1 Exchange the `a` and `B` keys with everyone in the group. ##### Party 1 $m_1 = H_s(b_0B_1)$ $M_1 = m_1G$ $m_2 = H_s(b_0B_2)$ $M_2 = m_2G$ $m_3 = H_s(b_0B_3)$ $M_3 = m_3G$ ##### Party 2 $m_4 = H_s(b_1B_0)$ $M_4 = m_4G$ $m_5 = H_s(b_1B_2)$ $M_5 = m_5G$ $m_6 = H_s(b_1B_3)$ $M_6 = m_6G$ ##### Party 3 $m_7 = H_s(b_2B_0)$ $M_7 = m_7G$ $m_8 = H_s(b_2B_1)$ $M_8 = m_8G$ $m_9 = H_s(b_2B_3)$ $M_9 = m_9G$ ##### Party 4 $m_1^0 = H_s(b_3B_0)$ $M_1^0 = m_1^0G$ $m_1^1 = H_s(b_3B_1)$ $M_1^1 = m_1^1G$ $m_1^2 = H_s(b_3B_2)$ $M_1^2 = m_1^2G$ #### Step 2 Exchange the `M` keys with everyone in the group. $H_s(b_0B_1) == H_s(b_1B_0) == M_1 == M_4$ $H_s(b_0B_2) == H_s(b_2B_0) == M_2 == M_7$ $H_s(b_0B_3) == H_s(b_3B_0) == M_3 == M_1^0$ $H_s(b_1B_2) == H_s(b_2B_1) == M_5 == M_8$ $H_s(b_1B_3) == H_s(b_3B_1) == M_6 == M_1^1$ $H_s(b_2B_3) == H_s(b_3B_2) == M_9 == M_1^2$ | Party 1 | Party 2 | Party 3 | Party 4 | | -------- | -------- | -------- | -------- | | $m_1$* | $m_1$ | $m_2$ | $m_3$ | | $m_2$* | $m_5$* | $m_5$ | $m_6$ | | $m_3$* | $m_6$* | $m_9$* | $m_9$ | This gets us to 3 of 4... Deep breath... and around we go again... $H_s(m_1M_2) == H_s(m_2M_1) == s_0^0 == s_1^0 == f_0$ $H_s(m_1M_3) == H_s(m_3M_1) == s_0^1 == s_2^0 == f_1$ $H_s(m_1M_5) == H_s(m_5M_1) == s_0^2 == s_3^0 == f_2$ $H_s(m_1M_6) == H_s(m_6M_1) == s_0^3 == s_4^0 == f_3$ $H_s(m_1M_9) == H_s(m_9M_1) == s_0^4 == s_5^0 == f_4$ $H_s(m_2M_3) == H_s(m_3M_2) == s_1^1 == s_2^1 == f_5$ $H_s(m_2M_5) == H_s(m_5M_2) == s_1^2 == s_3^1 == f_6$ $H_s(m_2M_6) == H_s(m_6M_2) == s_1^3 == s_4^1 == f_7$ $H_s(m_2M_9) == H_s(m_9M_2) == s_1^4 == s_5^1 == f_8$ $H_s(m_3M_5) == H_s(m_5M_3) == s_2^2 == s_3^2 == f_9$ $H_s(m_3M_6) == H_s(m_6M_3) == s_2^3 == s_4^2 == f_1^0$ $H_s(m_3M_9) == H_s(m_9M_3) == s_2^4 == s_5^2 == f_1^1$ $H_s(m_5M_6) == H_s(m_6M_5) == s_3^3 == s_4^3 == f_1^2$ $H_s(m_5M_9) == H_s(m_9M_5) == s_3^4 == s_5^3 == f_1^3$ $H_s(m_6M_9) == H_s(m_9M_6) == s_4^4 == s_5^4 == f_1^4$ ###### For the sake of brevity, the table below shows which `m` key enables the party to calculate the related `f` key via the standard key exchange(s). | | Party 1 | Party 2 | Party 3 | Party 4 | | ------- | ------- | ------- | ------- | ------- | | $f_0$ | $m_1$ | $m_1$ | $m_2$ | | | $f_1$ | $m_1$ | $m_1$ | | $m_3$ | | $f_2$ | $m_1$ | $m_1$ | $m_5$ | | | $f_3$ | $m_1$ | $m_1$ | | $m_6$ | | $f_4$ | $m_1$ | $m_1$ | $m_9$ | $m_9$ | | $f_5$ | $m_2$ | | $m_2$ | $m_3$ | | $f_6$ | $m_2$ | $m_5$ | $m_2$ | | | $f_7$ | $m_2$ | $m_6$ | $m_2$ | $m_6$ | | $f_8$ | $m_2$ | | $m_2$ | $m_9$ | | $f_9$ | $m_3$ | $m_5$ | $m_5$ | $m_3$ | | $f_1^0$ | $m_3$ | $m_6$ | | $m_3$ | | $f_1^1$ | $m_3$ | | $m_9$ | $m_3$ | | $f_1^2$ | | $m_5$ | $m_5$ | $m_6$ | | $f_1^3$ | | $m_5$ | $m_5$ | $m_9$ | | $f_1^4$ | | $m_6$ | $m_9$ | $m_6$ | </details> # Output Creation[^first] $r$ = one-time random transaction private key $n$ = index of the output in the transaction as a varint $R = rG$ <sub>(one-time transaction public key)</sub> $D_1 = rA$ <sub>(outgoing key derivation)</sub> $D_1^s = H_s(D_1 || n)$ <sub>(outgoing key derivation scalar)</sub> $P_1 = D_1^sG + B$ <sub>(output key)</sub> # Output Scanning $D_2 = aR$ <sub>(key derivation)</sub> $D_2^s = H_s(D_2 || n)$ <sub>(derivation scalar)</sub> $P_2 = D_2^sG + B$ <sub>(public ephemeral)</sub> If $P_2 == P_1$ output is ours # Key Image Generation[^second] ## Normal Wallet $x = D_2^s + b$ <sub>(private ephemeral)</sub> $I = H_p(P_2)x$ <sub>(key image)</sub> $I = H_p(P_2)(D_2^s + b)$ <details> <summary>N:N Wallet</summary> $x = D_2^s + b$ <sub>private emphermal</sub> $x = D_2^s + b_0 + b_1$ $I = H_p(P_2)x$ <sub>(key image)</sub> $I = H_p(P_2)(D_2^s + b_0 + b_1)$ $I = H_p(P_2)D_2^s + H_p(P_2)b_0 + H_p(P_2)b_1$ </details> <details> <summary>N-1:N (2/3 Example)</summary> Parties have the following keys from the steps above. | Party | Private Key #1 | Private Key #2 | | ----- | -------------- | -------------- | | #1 | $m_1$ | $m_2$ | | #2 | $m_1$ | $m_4$ | | #3 | $m_2$ | $m_4$ | Therefore, only **two** of **three** parties are required to participate in key image creation using unique keys. $x = D_2^s + b$ <sub>private emphermal</sub> $x = D_2^s + m_1 + m_2 + m_4$ We cannot reveal our private `m` keys $I = H_p(P_2)x$ $I = H_p(P_2)(D_2^s + m_1 + m_2 + m_4)$ $I = H_p(P_2)D_2^s + H_p(P_2)m_1 + H_p(P_2)m_2 + H_p(P_2)m_4$ </details> # Signature Generation[^second] The final signature (on the real input) that makes everything work is based upon the following math: $a_1 =$ first 32-bytes of the real output signature $a_2 =$ last 32-bytes of the real output signature $s = a_1 || a_2$ the completed real output signature $k =$ random scalar chosen for the real output when preparing signatures ## Normal Wallet $a_2 = (k - a_1x) \mod q$ <details> <summary>N:N Wallet</summary> $a_2 = (k - a_1x) \mod q$ But again, we cannot reveal our keys, so we need to re-work the math a bit using the same methods as above. $a_2 = (k - a_1(D_2^s + b_0 + b_1)) \mod q$ $a_2 = (k - a_1D_2^s + a_1b_0 + a_1b_1) \mod q$ $a_2 = k - a_1D_2^s + a_1b_0 + a_1b_1$ <sub>(all values are already scalars)</sub> </details> <details> <summary>N-1:N Wallet</summary> $a_2 = (k - a_1x) \mod q$ But again, we cannot reveal our keys, so we need to re-work the math a bit using the same methods as above. $a_2 = (k - a_1(D_2^s + m_1 + m_2 + m_4)) \mod q$ $a_2 = (k - a_1D_2^s + a_1m_1 + a_1m_2 + a_1m_4) \mod q$ $a_2= k - a_1D_2^s + a_1m_1 + a_1m_2 + a_1m_4$ <sub>(all values are already scalars)</sub> </details> [^first]: https://cryptonote.org/cns/cns006.txt [^second]: https://cryptonote.org/cns/cns002.txt