Confidential Transactions

With the introduction of RingCT (Ring Confidential Transactions), the value of the amounts transacted are now hidden from the public. In this section we will explain how the amounts are hidden via 'commitments' and how to prove that they are what they are really supposed to be via 'rangeproofs'.

Commitments and range proofs in Layman's terms

Commitments

We would like to hide from the world the amounts in a transaction except for the sender and receiver. At the same time, we would like to let the world know that the amounts transacted are balanced (inputs = outputs + fees) and that they lie within an expected range. Let's first start with the first part.

Suppose that Alice would like to send 17 XMR to Bob but she doesn't want other people to know it. So, instead of communicating the value openly to Bob, she would make a 'commitment' to a value and reveal Bob what she has commited to.

She could simply try to hide the amount by multiplying it by the Generator of our elliptic function, which would like: $C_a = aG$ and then secretly communicate $a$ to Bob. But that doesn't really work as anyone multiplying 1 up to the maximum quantity of Monero (~18M) could create a table linking the point values to the amounts. After working hard and many attempts, she gave up and called her friend Pedersen. Finally, they came up with the idea of creating a binding, hiding and homomorphic function represented below.

\[ C(x,a) = C_a = xG+aH \\ \] Where homomorphic means: \[ \begin{align} C(x_1,a_1)+C(x_2,a_2) &= x_1G + a_1H + x_2G + a_2H \\ &= (x_1 + x_2)G + (a_1 + a_2)H \\ &= C(x_1 + x_2, a_1 + a_2) \end{align} \]

Now Alice can create a commitment $C_a$ with a value $x$ which we will call 'blinding factor' multiply it by the point $G$ and add the amount $a$ multiplied by the point $H$. As there are many possible combinations for $x$ and $a$ giving the same commitment value $C_a$ nobody can guess what $a$ is.

She can now communicate $a$ and $x$ secretly (encrypted as message) to Bob (as shown below) and the world (except Bob or someone holding his private viewkey) would not know what the value is.

\[ mask = x + \mathcal{H}(\mathcal{H}(rK_B^v,t)) \\ \] \[ amount = a + \mathcal{H}(\mathcal{H}(\mathcal{H}(rK_B^v,t))) \\ \]

This solution was implemented at hardfork (v10) to save more space in the blockchain. They started being used at transaction type 4. \[ mask = \mathcal{H}(\text{“commitment_mask”},\mathcal{H}(r k_B^v G, t)) \\ \] \[ amount = a \oplus_8 \mathcal{H}(\text{“amount”}, \mathcal{H}(r k_B^v G, t)) \] Where $\oplus_8$ means to perform a XOR operation between the first 8 bytes of each operand ($a$ which is already 8 bytes, and $\mathcal{H}_n(...)$ which is 32 bytes). Recipients can perform the same XOR operation on $\mathit{amount}$ to reveal $a$.

So, if Bob wants to retrieve the amount that was sent to him, he would need to know the 'transaction public key - rG' which is communicated in every message, his private viewkey and the output index t, which is just the order of the output. He can then simply, do:

\[ \mathcal{H}(\mathcal{H}(rk_B^vG,t))-mask = x \\ \] \[ \mathcal{H}(\mathcal{H}(\mathcal{H}(rk_B^vG,t)))-amount = a \\ \]

Now he knows every coefficient in the commitment equation $C_a = xG+aH$ and can verify if that is valid.

Verifying that amounts balance

In bitcoin and other open ledger cryptocurrencies, it is trivial to verify that inflation is not happening by directly verifying if the amounts obey:

\[ Inputs = Outputs + Fee \] \[ Inputs = \sum{a_i} \] \[ Outputs = \sum{b_i} \] \[ \sum{a_i} \overset ? = \sum{b_i} + f \]

By using the homomorphic property of commitments one can verify that inflation is not happening by checking if the commitments balance.

Consider the input, output and fee commitments as:

\[ C_{Inputs} = \sum{ \left( x_iG + a_iH \right) } \] \[ C_{Outputs} = \sum{ \left( y_iG + b_iH \right) } \] \[ C_{Fee} = fH \]

We would like to verify that:

\[ C_{Inputs} \overset ? = C_{Outputs} + C_{Fee} \] \[ \sum{ \left( x_iG + a_iH \right) } \overset ? = \sum{ \left( y_iG + b_iH \right) } + fH \] Since we do not know a relation between G and H, we have to assume that: \[ \sum{x_iG} = \sum{y_iG} \] \[ \sum{ \left( a_iH \right) } = \sum{ \left( b_iH \right) } + fH \]

Therefore, if the values are positive and in the allowed range, checking the commitments is the same as checking the amounts directly like in bitcoin:

\[ \sum{a_i} \overset ? = \sum{b_i} + f \]

Range proofs
Although Bob is satisfied and he knows that Alice correctly commited to the value $a$ that corresponds to the commitment $C_a$, the rest of the world does not know it. So, Alice still has to prove to the network that her commitment is valid otherwise her transaction will not be accepted. Alice can do that with the help of Borromean signatures, which are a sort of ring signatures combined with a zero-knowledge proof. Its goal is basically twofold: 1) Prove that the amount, blinding factor and commitment are coherent. 2) Prove that the amount that Alice is sending is not negative and lies between the minimum and maximum supply. Let's see how it can be achieved. Let's start with Alice commitment $C_a$: \[ C_a = xG+aH \\ \]

First, let's get the binary representation of a, where k = 64. (The total Monero supply, before tail emission starts, is $2^{64} - 1 = 18446744073709551615$ indivisible units). We can factor any amount into its binary form.

\[ a = a_02^0+a_12^1+...+a_{k-1}2^{k-1} \]

Next, we generate random numbers $x_i$ and we store the $C_i$ generated:

\[ C_i = x_iG + a_i2^i H \]

Now, we want to prove that the sum of all $C_i$ is equal to $C_a$, as the amounts and commitments are additive, ie. $C(a+b)=C(a)+C(b)$, which means:

\[ \displaystyle\sum_{i=0}^{k-1} C_i = \displaystyle\sum_{i=0}^{k-1} \left( x_iG+a_i2^iH \right) = xG+aH = C_a \\ \]

and this will only be true if the following holds:

\[ x = \displaystyle\sum_{i=0}^{k-1} x_i \] as we know that: \[ a = \displaystyle\sum_{i=0}^{k-1} a_i2^i \]

Finally, we observe that $x_i$ is either the private key of $C_i$ or $C_i - 2^iH$. As shown in the equations below:

\[ x_iG = C_i \quad if \quad a_i=0 \] \[ x_iG = C_i - 2^iH \quad if \quad a_i=1 \]

Now, if we had a way to prove that we know $x_iG$ without revealing $a_i$ then our mission would be done here. Yes, you guessed it right. We will create a ring signature where the participants are the public keys ($C_i$ and $C_i-2^iH$) and sign it using our knowledge of $a_i$. Therefore, the external viewer can be sure that the signer knows $a_i$ without revealing it.

As intended, we proved that we know $a$ (by proving that we know the entire binary decomposition of $a$) and that it is a positive number that lies inside the money supply of Monero. Therefore, by proving that a Borromean signature is valid, we validade that: 1) the commitment, blinding factor and amount are coherent. 2) the amounts are in the expected range.

Hiding and verifying amounts in practice

Generation of Borromean ring signatures

To generate a Borromean signature, let's consider the function generate_Borromean(x, C1, C2, indices) that outputs the Borromean signatures bbee, bbs0, bbs1.

You can consider $x$ as a key vector with 64 keys representing each of the $x_i$ values, C1 as a key vector with 64 keys representing each of the previous defined $C_i$ values, C2 as a key vector with 64 keys representing each of the $C_i - 2^iH$ values, $indices$ being the binary representation of the amount.

Consider $n = indices[j]$, $p = (indices[j]+1) \, mod \, 2$ and $\alpha_j$ a random scalar.

For $j = 0 .. 63$:

\[ \begin{align} L_{n,j} &= \; \alpha_j G \\ if\;\; n& == 0: \\ &bbs1[j] = random\text{_}scalar() \\ &c = \mathcal{H_s}(L_{n,j}) \\ &L_{1,j} = bbs1_jG + c C2_j \\ L_{hash}& = L_{hash}+L_{1,j} \\ \end{align} \]

The signature bbee wil be $bbee = \mathcal{H_s}(L_{hash})$

Now, for $j = 0 .. 63$:

\[ \begin{align} if \quad &(indices[j]) == 0: \\ &bbs0_j = \alpha_j - x_i \, bbee \\ else&: \\ &bbs0_j = random\text{_}scalar() \\ &LL = bbs0_{j} \, G + bbee \, C1_j \\ &cc = \mathcal{H_s}(LL) \\ &bbs1_j = \alpha_j - x_j \, cc \\ \end{align} \]

The signature will be: bbee, bbs0, bbs1

The following Python snippet shows how to verify the signature according to the equations above:

def generate_Borromean(ai,Ci,CiH,b):
    alpha = []
    bbs1 = misc_func.scalar_matrix(64,0,0) 
    bbs0 = misc_func.scalar_matrix(64,0,0) 
    L1 = ''
    L = misc_func.point_matrix(2,64,0)
    for i in range(64):
        naught = int(b[i])
        prime = (int(b[i])+1)%2
        alpha.append(dumber25519.random_scalar())
        L[naught][i] = alpha[i]*dumber25519.G
        if naught == 0:
            bbs1[i] = dumber25519.random_scalar()
            c = dumber25519.hash_to_scalar(str(L[naught][i]))
            L[prime][i] = bbs1[i]*dumber25519.G + c*CiH[i]
        L1 += str(L[1][i])

    bbee = dumber25519.hash_to_scalar(L1)

    for j in range(64):
        if  int(b[j])==0:
            bbs0[j] = alpha[j]-ai[j]*bbee
        else:
            bbs0[j] = dumber25519.random_scalar()
            LL=bbs0[j]*dumber25519.G+bbee*Ci[j]
            cc = dumber25519.hash_to_scalar(str(LL))
            bbs1[j] = alpha[j]-ai[j]*cc

    return bbee,bbs0,bbs1 
Let's consider as input parameters the following variables:

ai = ScalarVector([Scalar('31e8e973a92660fb77411e1aa2e0613c67de3427af5310ff4019a0bbe328970a'),Scalar('74b957c45fd00586bffd69da78d2ecb8394c49ec8917afbaccb062df2370d10a'),Scalar('0d6039a300d62140e9882bf014f5fddaf57c06f2c94d3c38042c0530717c3c03'),Scalar('a159d232b162812aad7f5db2f56529cf975cb60045b0a7af6c46ccaef8d8cb0e'),Scalar('e0e850d2beeac78167ec3da556750a362a8a0059e45e3c8c3277d91a640f8803'),Scalar('a8314694b74517602f4df4122a5d5a09b394c047f5390aed4d0daaeea9c95003'),Scalar('dddcf333016f20c631e0534fd76ecf36536d89d99e19d856fa4e16c08a260909'),Scalar('93f5b834303cb511b76b728b56180f7a451d82ce6504714180c3f99163981600'),Scalar('22839d54a07f87e1bc0e56581e5945df2a4a22e4453e4c9b89cffa509182c70e'),Scalar('518fe700774f583b0f47b6a07897112996e2307f7530a7371b490e6f8efd1104'),Scalar('da2cece9eaacfeb03b5290da44b53ff8f0507cf87e4a4b3b5a46fc6540814a09'),Scalar('ed919594606b2540f9f41cf568bc93f7008bfc9b0277167fdb2386fef8333d0f'),Scalar('848eee21e6a5f5c628381d5c7480793507663b8bef04d89ee326bc1f45871001'),Scalar('211109e88a770ed0eb7435faed724c335d49ad2eec387f61c5aabf8b4e5ee90f'),Scalar('80200269fa25c93806de2ee21ad48bfc6edb482fa695391202d29a5fb1ff910d'),Scalar('7b5d64d3673feb73d2e9f8598b690f12270869bd1503812fd60122600e20d405'),Scalar('e19b75ad4826b305ef5e4e917c34e4e09d6fa1efbd65f74c5ac4975e9874c304'),Scalar('bb2be9195789db32dfb2c6eeddd6c5a3ad8af0c40a667933b3f4beb8ef189f00'),Scalar('50ec78937b20cdfe3ef39953455ba1bca118deb108e32ceeab96517c2cbd740a'),Scalar('58a3984da41880c3c0d302df41d7fbb36733c8cccbf258a15ba012cc8ef13607'),Scalar('706502c1774d9f478bda5c823c87bd354dfb8cebc1a18e2a3182fb4797632c05'),Scalar('d00ed1e29a14958e62f35ed5f1755f93ba507e5078353e2f2c09706df409df04'),Scalar('d1238a8ef68657f9e0599c21a90e257102ade63686ec2edf7524129cf9715f01'),Scalar('ce15b635bfff3b3259e3d1427ddccc8b4ca8553e8623d232ed549304fb54e708'),Scalar('88dc65a925d9d6d2e6561b572fb236a133564b9f7daacc7a40c817cab664170a'),Scalar('449c90eca9eb37247de83c40897d1ef64c4dafc121d866e18b93b85d38e45700'),Scalar('abfff6b9678fef29db096ef78740373fc1c048d3e9f94f9e9473bf8fc84fec08'),Scalar('4e788552172402586b0a4fc717730c29aa4c36e9e52028db2df042d5721cf20f'),Scalar('3fc465de4570e1a566fbd24890692aabb93d07509e3bccda05fa5b3c4737260b'),Scalar('852c130aa7b6544b82b83fce4ac41cec0fe0aeb68e09b45b866128332ba36c0d'),Scalar('6b2723fcfb787a219fb9be8f095e0ab49b8c2d7f99689e8e95b78098757f9f0d'),Scalar('746bb1ec980f3eabe4dda078e30ead620ff0ee2c511962b0747bb40c6946f300'),Scalar('903d520955feb1cfca1373739256d849e23184a9012e4f54e9a08fc745141b05'),Scalar('413bb35047b33398322633fff715faa667326d05b56b6d974e071bdc1be23709'),Scalar('a2a1dc60cd5b3888c1f58ac724f1fd61865dd1068571481685172cc1072dca0a'),Scalar('7e5e993bc520841c77751edcd3f7110c1af94b06a423e4961ee2d71722190b04'),Scalar('b0659fb7b7555bfee169c8a84719820eb9254765c879c42d093287135ef8c000'),Scalar('2b91a58f12635829768ecb20cf18fb7e88f673281ce066be26c4b15448fd5902'),Scalar('a3b5352eb58d076c665faa3aa4f01a8d0b3e6a7624d78f08ab8e83deca12bc0f'),Scalar('7a0d30236f597ce6640757a501504c91703429b6e99fe8e4decede6041ccd504'),Scalar('cc5ab38561cb09f98342f3af7bc1adc8b624820986843ef8c057042655589c0d'),Scalar('c9e2056b5644741d773d44105afacc206d039511f6623466661f4340a32be00f'),Scalar('37a7dc10ac40810a64bca8b37cccefd3a58f953ea0a2e2790eb0194368232602'),Scalar('066ef80d1a8ed35b4f001c8343d4acc391f151376de8c6e0556de90430ff490b'),Scalar('fa03fd08e2a236366d09e291a486389e6844f88918ae5fcd2290507fe991a509'),Scalar('95478138e509fe4552df11095ffec2fcc315c762f06c7b6ce762c2d28ed29b04'),Scalar('498a51fb37431c669ca7010ccd9a99f0c5e9ba1ef55bab10f256780434ddaf0d'),Scalar('06363c6f8eda5c610a8ba6ce2157280c17b4f6472614320be121cd0ddd5f670a'),Scalar('3d114496acd7a93d66185a359654c22b6615170ff99b9758997bdc04aee21304'),Scalar('ed4b59bbac87b1b5930986789a4e38fd9fb88de1606f26fcb9add47bb454c306'),Scalar('ecb21053fbc3fbac4401c77eec410752ed1ac3635bd11745700d89901c499d00'),Scalar('b17c1ae4c8243efda39b5350c1f02a6bcc368265e8836e39c7b204dfd43ba900'),Scalar('61cff22ee225413b00c328983c2afb3bafd0f8ab8179ce73b02cb311c8338b06'),Scalar('53cca2971deaef2a140b954f4b6424bcf060a537c39b3d6e4490370056f48a0b'),Scalar('9260d69d32d38875d9b19a604a00b558463df8faf92a0d169a8c32ea731a8f0d'),Scalar('5fb932c693ebcda1de2cf1a3fb31b5d3044eb8ca071c0bab024f2a53bf26a607'),Scalar('8a4f4513eb13c5300839c311a54033f3f6418c9d18f858297a3f315d377ea80c'),Scalar('2bf955bbed082cb63f49f7707ef4790518fcf46f66ea0bf476594edfbd2f010e'),Scalar('4d559edd2a7035abe4e09da97c900b72cefe746235a79a14cd1903dc39c56907'),Scalar('71ecc4b6c26e36868b390552dcd0e6652475ee999fd68705938ae0843ce44b01'),Scalar('5136da772ac4f3de8ba79c0d0a52fc1c57c6c1724fb6a14bb3f92f4333f42c02'),Scalar('3c0bdd291d329a114d3c668e208ce3276b8f0fa14f16178ff0f0ef2f97515901'),Scalar('5de08447e97bbc23f7b8ad25cad0bcdd23426ecb692c1d35cae5e943320c2106'),Scalar('7b074fb2b2da5425af7bdfe56ab16940a60b8b03bcb663c1d7113b2f1a3ac404')])

Ci = PointVector([Point('45dad70a0b2d5d112656a308c0c601abd5ea55cb0e3ecb36e82329a41968a7be'),Point('9c038c6122162cf6716b2afd15e183c1f31372984b0036483780d0b1772849ba'),Point('4bdbcef1a675c51b572dd68dda2cffb8304bc91085811c4b65ef8ecb68b416be'),Point('557b24a6d0a7f198c0bb97a31d8b805f8969b31139901b61f341890634480b13'),Point('511219d71f7b1fc4b09a3cc65378a78ed64575082524502794e74ae00387a7cd'),Point('10ec3103d8ec01d46bb15305555ab03b639ab22f13caeb15326b2187910a6f7d'),Point('2358c2ca61cc4c14a8c1b5d22d68ad9832c343202a51541eb930658ebd944eb0'),Point('b4d79f87b2579cb98297d55e288589ebaf9faaf7903cd866d1bc2cd783624949'),Point('0d120c1f28601cb9840140cc54abacce0c2723b0955f1383025adea0152103c4'),Point('33cf57994fa6e7f8bec0e0d2ff740623fc5782c38a9732d021c59d5fa2211a75'),Point('3097c57c497a29f0b444c099ebf3753adeab8b9fd9c9b317301681c92263623d'),Point('97db38f6f7013d1a74ae5dc9d29d2096f9c4104746c5f390840dff086b4940dd'),Point('60b4b3c0ef2e61fb249bf1974bdbf2ec249f2d22b29db06b1b429cd73d31027f'),Point('0f0d6dcd212534965337b9561a71b1677e90932c995617c8c7d034a7c13d87a2'),Point('4c391c5d2800ae8fe65dd0af8a48343f7390bd090f81f499892d637ed4522a32'),Point('83464feeda9c916340a85878524f122ff1176f3569cb94107db33c9516ff80bc'),Point('2d176446a45e4d48f9bab841a8fe56f11f5a2394a1de829e08fa7534f5eab794'),Point('8598d5a559d1d4492a42c8151a0ba6e8502793f9da7d30d04fe466a0c77d4086'),Point('e37743bae7f5ad5653d5e866ab37ef421d55dfab456d9cc2eab7c8f6bbb2f598'),Point('816c56a6cd630917efcbcf42a4585bfaed75015c13f90915ee9d7ace6ea22196'),Point('cfe2614db372bb5dff6e9811c6d055a242784a8dd48d6abcf25f377853ada97f'),Point('4445632f27b43cdb361c492800230dcfca16a8bbbd78ab001a61f3c7b7f83ef1'),Point('c6da1adfe0973f9511baafbb6fec4339901b9f08927d1970880fc7a662caaeae'),Point('2d829c3ab83eebb41641e81070af4977778a02e26173528ca3e833dfeaa5fd2a'),Point('aa97a8d4aa48cee8f585813d60a97efc55985108c4b77520c9b69a1b1ad04e85'),Point('a33569373f5a50e1c93c6baee9f600fcb6106469f31c04369919397837fa4743'),Point('bbd0e1b516ba9c9b24d3e1b5a71d061848da58213b5c14c5fa655c869095c3c4'),Point('b00bf895382f879300a7779791539e2c7862fec984fb30501125f46f29381e5a'),Point('ed2e6a18dfc1d6024a75c4edb1968839c26d32cccdf233356c6b6a7ff0a47dd9'),Point('096dc77c4aad66917993bf55c53b92e9e4e477a54e8d02605072ba9a22d65821'),Point('8af0dab9e092568c3832dfea2be61eb02ad3c984338407aabf8c69bbfacf558b'),Point('220abdc1086ef49c27528be0173562abc69e8b29ab832ed7a12004f16e392ec2'),Point('b72b0bb174d3367d45e777ea512e4e88ac97ecffc1c1f3be43449a811d0dc719'),Point('451762c1aa0f65e545c25f2542bc66d8839945c56f10647339fd2262956272a8'),Point('9b56499984be2215f21b69f66da856ad07cca328fa21a738cea8f1b720e9fbca'),Point('b14de11fc2679cd80bf60ce111e1d11f8253aed524fc1363748d1eefa902dff7'),Point('e7492d16bf140108f25e22d6cebbe2fd41fb6a457b497aa0f9a294bc7329f779'),Point('c03c23364c18ae9543686b02d7a71c5c714069fdb50706488e0cea1291f4b1e4'),Point('97dc3baad97aba1daf5b731fdf4462633da810dd23910b8b7d7202e2c44d2384'),Point('57f8fcb0a9ee937aa7232c847d3e5a309053a4b5c8ab13870c983808ce047f18'),Point('ecf6940c79ef5cb8dcd729e56a581853279c88b40a138329253808a48e3e2126'),Point('4ce2dc8c90454e9647271d26c7a3432bacf724441cd005e59f20f23cec5b5c49'),Point('f3d78af28737711767f15feb6797e48b59803c5b88dae3566da4c8ca7895e489'),Point('7b055fd807458510082d84ccc2a87ffa7bd4a0e477a358fd7a50e565c68f413a'),Point('5be7111548f32b5c6491620b182dd14ea206e5ec1f80a39e05d1315ffe23148e'),Point('482054905f125fb322b2c9b3cae0e0a476857e6612e8f1f0270e71b042922de1'),Point('99de2c3363df6580be8e42c2b0b499a24b07f7c527844dd038a4c2acd305a1a0'),Point('9a20c0fa618e90471b2fb1e9a7acbe95fc61cc823804e176a5888feec7e0840b'),Point('1eff8019c8468ef4536661ff1d6ff267a43951f7b6f615cc681660108c3ec7ad'),Point('3d61d2beda2071fb8bb8ca723fdfc0a7deee7e350bae7ea57635133f9b00f415'),Point('12cdafb4c93b13cbe155a72a189480f28767dbacc6ac509d29229986fad753d4'),Point('6e123de83280a900d9479fc728059a0090a0b3f691e52497d5b6a7aa8a105e42'),Point('957fdf381d884607b46e1e4bbb59a9c59ac664f35d6e20038d3514830a50a55a'),Point('4ba30efa3ae4312a7ad4b31f0377d10068d035d18b7293dd0151794ebd3d03a1'),Point('d589778991acb83bdb4e1f3f475d009f3422c12be06122e38ee8295883ea519e'),Point('7977c086e3fd1b60e9adda0a08c44c37459fba8c04b83864ee9f4de2eadbc091'),Point('62d696c6dd0fd5f9ef59c822138f72d0e8f0deba819c212531192223a07e25c2'),Point('94a40baf738de9949f353ec4b261283dfd4a4e82221fcbfe10e7e9f4f95f3038'),Point('939fa97d836dfd629bc2ea996cef0b6d11b10489929927005ba42f5ad6d08940'),Point('b3949629fa3e7dbb63f2fae0fc526e7336bdce651a4661a02069043ca4db13af'),Point('fb317da19df1e17ec9defed2f0650554c4b4f9f7027e155e3a7cde120e33e8c9'),Point('bf9adea2748df1aa9408b602fe2e399a9f544d457d43c5a5915fb71be1c49a06'),Point('36ab6ea200178668aa8116bd1f55d306d55679358b624ba36e13ad80466f9596'),Point('8e496cbcebc0c8bd0dca123be547d3399921dfb6ff50849f55b043fe3ef729f1')])

CiH = PointVector([Point('1c4fa29382ffda9cedbce619818953eae271508d0395e34a5914f268c3aae746'),Point('52fa6842b0b30ac501ba923c3bf2c645b858a2663385cb9906c9ce2f1ad74bcf'),Point('cebdc1399a5d4b96c19e8d2b1f9551e02ba77ba7f209aef98a5d5d48b921ab7f'),Point('1ed057f1e343bb0e14fec57439dbab915b3773fa75edd03b7720660e927be6dd'),Point('4aaff4771af57a6d4db143a9f88d510ebacb73e2795aa44c8505cf0ec4eb4e88'),Point('e3be67ced77bd0e4e05c1dda361b881f274e53fde5dacdd882dc4e6e3c9aaba3'),Point('0e696cef384d90304792c3dad219a7c5efd394316c52bb7ac4df4b5cf71ed34c'),Point('cbd5154fb97f46e6aff3031bb3b52e24b54bcf87b83835c8de0df34ebafeadc6'),Point('a14f040b8b481f4c1212456f804292da7c36e9e7d6218287790caedb8a337a73'),Point('a425548389ae0f7783653d650aa60558bd25a29731dbb58dd74fa50e468e7ad1'),Point('11a4d85f31f3744b3482d57f4c1c4f27ca926a54bb19e98dfc2ed6232acb64ea'),Point('253eb26ad06f04d7e237744eb2e4ab190074b5d32a26996915bb658896f9e5e5'),Point('0a4a5e78c05f55d628e0e9135df91ea4fe2f55bc282b1a9325a93e55ac354581'),Point('50281c92bc95950e64b6d557c347897cfb1f8c0343cddce9806d36dfead21799'),Point('83317a5f89eff8bcf96ccabfddb168ce9e76f1f5be9b10c43b1ca9b5a6a3a2f3'),Point('e4ca55055e7c2c94963b389b598c4868c8d4e78511620b3e01a91a083ba6a24a'),Point('a9ba6b070ced39e918465b185ade582ef07bd0e2781419620498932882386770'),Point('a9c292d5c4fc9116e0352c07fcf69bd285c1448c3b81e77b2e8c293ca70d63a4'),Point('ca76af5e4c65326fb57a816b60adf9201cdbf6a62bc0ba987583371c9156cac3'),Point('b0db11a7be6a244c39da5f82a147ad3ef6878726c6e88e4c34f8ebf679ec916f'),Point('1395df1267916b4a4d08b2203ac0117a1565e12c894aef6209902f392be568d6'),Point('ad538a6685c6447ab1e4b12156e62815b17a0e095e4dfaf79c34a1c5dd941889'),Point('e1d428e82f8fde3b0d0be55e0c4f5b68274d1e909ea5845d5a13f078956c2d84'),Point('5d3376a92acf4f11864d1f847f14814d2be2339912a69435dbed464f9297962d'),Point('12ec63d108b52b8fc0a33a01acf2003ad40a60bbee1b6b3da93700a2af7d1bc4'),Point('d10048871cfe14f6e779deb60ae373d2bf5c4074ec3d562928183d6fdc98218c'),Point('4abd9a88be5672fa15b33458702d3c0df3ae93915175105517e16feb2415eb03'),Point('7418e7a8b5a762a432ff75d1b5c01712d7ba1dd8f055dd4be9bd0bc9da0cbf89'),Point('2deeb51bf1a873cae155a414a067b325deb5b4313e744fc67796888d3af986d8'),Point('46496bce75ab92a3c32d59b99181af100a0925b589ff6812167ba1cd4693900c'),Point('acf5b98ad3b3e7750a7f7a2c02104e2109c8646d08319fad11c6b2eb78e2055e'),Point('b7744076966aa42b38b42d97337b8c458c0131befc93eed150d26c73f288fbfe'),Point('ba854ca543e95000a96b58c7a34a010fae76fca25ba78639e1ded38bae298a54'),Point('1fa1c7d7290b0b555368bb8b57d959046bce41b849c3a444c91f124d4030f538'),Point('749463269d70ebb0460c1f088c89e5df358923b9ad6e82ec4132887e34f4077c'),Point('f74b3c22e7044bcd64d3bfc0aefd8ca1de2886f9f3050cd57b1afa92832643a1'),Point('5f211f5963d71b1aacb8c8c6a7e74a3750f8f79cf61e00ed95c3855de0151882'),Point('1f4aef366e14f10ace57fdadf45f0f5eea87af258c1dc5a185827bf170c17adc'),Point('67c190ae7543047cf52ed177d2e8e9ccb0c10ee519f0884813c9d96a7342c1b9'),Point('ddba136d26ebdb5d971b83f28ea2e5cb36ba6e3b5cfb9b0812dbb6274aa28afc'),Point('3858c78ab835bfa9cfba8fb6c7f71035c5a92976022a3833693ca1dc2814f276'),Point('25a040102b9692981fb703395fa2d6fcced83e30ac31df4a8138ee43a884a5fc'),Point('c108019bcbfda2e1f67b94f4a5580e7b54accd65967610eb7b31420b318bc9c8'),Point('f7ed068e884e534dbe251749f17a35d98c0953b311767d22b8b9a199bce25ccf'),Point('0c7920e77b727edc7232d965ea6839dba3ab4baa202924486a2ef84ac61d26a3'),Point('87d4a1ed3027fd571b1073325325f271d2576fa3ac3a168c31a092467a907241'),Point('6ea92dc4f66571426dc9ce8d2208aa13383f8743779436e92d0c2aab81c3015f'),Point('d698ffe7ea919e81c8dd476f3eee6775e0b36c9cc74231aa1b00067f74391a9f'),Point('18e6e8473013cb1c3d5eda73156ac0898cee8488085cfefceb5ebad6b043ce8b'),Point('bce6a426e7904964362b8efc5fb9b0e5c51e1e9f85f59add275c7a23aee6cce4'),Point('f61340ffd289cc91c0ab4535fbc43ce9fb08f1d6e61ca2e485911f1a7e9c5974'),Point('959b67b1412e1e7a3b8c3af6499b2a213fafd783b26521a04a896f05a189796e'),Point('b91ff4ecce8c095609a8453fc575dcb45e12451ef94cfbc58668b1aa4a56fa01'),Point('c10761b2a56a5093cd1e5a285107ef52bc5bf8f30b4c2ab20274cff6232386b7'),Point('de42b489ca3a3c453212a16d25d7d84e82d30330fdbe3ab49457242418b14247'),Point('9389476fe2c3d10933256063b6b5d8e773833b19e4b5e8261651faaf1d9ccc88'),Point('8a6d3d4e0ee80abc5d656228aa2353028a406a42256c4832abec9b8244766202'),Point('ae1747955870176075c410c3171a41f0435bf7ede553cf961260924417b43f36'),Point('3def4f89efcd41740392d577ede12852c82b2f5d6bc67a302b90d865779f130b'),Point('f3b0c77dd27bed9272a64117cc30fb78f282a4f49f931c13ae90bf67b3937de4'),Point('442a5f488d48fba50e76e69db675219250beb80b7cefe663d3274c7a4c2a055c'),Point('aa817e312bf2d5000da8553369284f0923b07630b014df21d453dce3d3b47ab8'),Point('de4a1d2dfa84b8b6a1d228672f989101764902396ac2503f69a38c98c2220480'),Point('48df54f63dba4216dc6783f8e2abeb17ffdb7dcc973bbf797213707012d407e9')])

b = '0110100101111110010001100011110100111100101110000000000000000000'

bbee,bbs0,bbs1 = generate_Borromean(ai,Ci,CiH,b)

Finally, the Borromean signatures $bbee,bbs0$ and $bbs1$ are:

$bbee$ = 28443a2ac7403b7c3dfb5ea1839ae45ac9d531ec4c531a6357f7ae98a7e3d80d

$bbs0$ = [38e79e22b62786ad40a20a1c3a0c3b305f35772f0d44a8e7b86f633d4ff05000, f645422841c61cfb189194417e55bbfa60db0e1f89155f95f3a45546861df103, c16e7f41f8343e06c81e97365e884b5ef051eb1aaf40627f79fa774b7b148905, 97b21b57b345ac1a4cdd3ffd8830217a0e331e17385b7b136a9913debfc05d05, aa0fbadc4206fac11f861969e1662bc25c31822dab22b53bc6b05d5e7428100c, 25e36060961d2197414c2cee74ef51e03834b5724deba6d60bdde7b3b6495a06, e3e892b16ff4ac4a641e984db7b15e80a23cf10800b72dbb6e1cfba6b6ffd908, cc38f2ffcdc477c856c6f6055928be0b9e4c7698a5e9b6fa0b82470abce81c07, 8d5a54e019eb311b64377712801055dfd2b8915ff4fbf136882d50bbad5ba502, 7e0f88ac3d63c9265075d0e8d38401812008c0b24b93dc172483595033842d06, cd83f97081713954cd4e7dcb85e865af298d00dced6de7a00d6b6e2a54917a07, b9073d96b280b020d61e7f2cce1df840b2c00d3c347db780a029f2092d446e07, c12e6c45c8ec38d49beb056d3f88160025fc828813779af9471dd2ac641e740f, c625f55bd186a1bf2133ebe5b8f9408c4fbdd7d56d697826c0967eec2909f801, 84f6ae7030f8142d84e8de286c8309477e4f8bb7888eafffc291a8a87111150f, baede58cf5bff5e03fa686ef6fb1a1315583f234ba11b7234a88798a38f9e20c, 9d833171dc0c4e56f4c0715a11a43805c6d6fe5a21fe0902faf700a6cce79501, bcf9f973fb58ba248b6c752c3d13f1228e80e67f434f163233c68e3e1d5e4d08, 579488cec93a761e2cede6cc5b4c38623f7b6b529b80ecb724738eda2258260d, f391337fd1fa55998fd4d2238335e4c287459a02a4f43877f28344312a865d05, 3498549e616d4388c32192e10b0f0d6be86dd5e3c9d4f5c1f333a0afd7dce201, 419dfc496a2a1829d16a76722090b5602549c54d976ad683fd43590ea6635a0e, 69a47d7de058b83845d1884eca09c9908b308ab5f20154579ef01de5da140d00, 8159f16978cff0351f4abe7b054f47650680c0b2b76a3f884ca8020b93a43a08, ee38b4a63d8d5049bdd9f3ede4f1990dc708a3502714d3c2a78d24547f4b5708, ffb43ca94e6559558cbe34d5399d68a455dda6d01b38667f98ca54f6f255530a, 4827f82345d958ef1ebf30d3e7b95bbd447ffb5f91e3d294999b54fa0ad49801, cb9fae07f480b13bd9822c28e1120330defefd5fe7619df49e80ed708fa0a209, e65e070ad266ed7827c43b5d6dd593334de8cf109f62c231eadf7d6d3a364007, 97e7aad3583dd16780776c0a1eb86bc9f744d35e93b668c367e2ee769dd33607, 1a98cc1d93e7ae2c4fb615fbe19a50e0ac40f53ffe9669d64d7e00b8bf04ac0e, 7e3840415d8bfb7391575c9ddc97273f3d85d7ea8d6b8d4741eea51bb2271e00, 9d76a2722ea64500e435f0b7e2315d0645ec55cf16d700d9e1a2dff29e2f0509, cf0d9189b6f6fc638dd60c1d8a98a11f3d969df675e1c3ea7656eaa122fce40a, ae7e3f17b0278bfecb48968b833ef2be5b363c3d441adebe234dad3dd15fed03, a542ccb592925e5e4a924f497f6dd79c39d277acbda61f2a02e83241ec575f05, 75ac19bf2537186188b0dd0f84a14d303da08c8166e616c814088b65a4cb7409, a3460065da772b3cd0ef14c687bdecb2fd9be94523305a1b41499fcdfb86d307, c25ad262779ce5114b57adca2c95f83682376093ac0d99abf70c8a315a5a3902, 59657b1e62c9cc456ea8d0c753b5c29f86d3cc9c1e52269c2438d52c3a8b4906, bf906f9f18a2667a9df0d9f8a5641aa1c06d3f4aff88a21448af492905494706, d8f51f05efe35d059982f8845ce5ca396514dca55afc3d36b4a9069ccceff305, 2956efeeb7a5a936630cee619ab10283da7d53b574df60a97427c86634346608, e2526ddd03b75773fd3c5c4e6d129df4efe1d49ad0ec5f0f767636e6525cc100, 760ac51af190719b6fa3081719762db4dc2be691a8016b14da4300a7e4df2c07, f512d4579cc662a210fffe30c17a2b07a74bc21646cdabc8f2b85b86d3a08801, 8f009a78bd966951fcdd0825dc2d41b36ae983687fcf97b22c9d06ac24079305, 4d3d94c6a123cbc8b7272383d49113f1e46c96b4e9c4604710aa111c16e8340f, 86f5ff383be5599c2617190e72e8527f8e5432f4627268f4c6599f77b3105a03, a0f309d036b9995e57bf7fa675f7ce10eda1a992902e67a6ab1ed6a18cb95f07, c563c518b89ec270b33e83a4f80a07dd558f147a715618d995dbae4407044209, 10f4f83ac640971d70828e0a9648e89db71072e670c86266182dfc3da348000a, a4852d2b3b5a045ae906436cc4c368f8853b73e67743029eea7931ae1ba58b00, eb71dec02512f4fdcf4a8791a34b74090d971a6ae5f9e1c09580d1ca0a39df0d, 2a067ddb2587a48cc114f6dd5c5994e7e8b522927278eef5a43d24ef41996201, d4682f6233773ad13fcff381ee983be1cb5e4872b9e28f33e7676d7584d1aa06, d771f957ce2812ee852c2b84b578b322f3e95c3d900cbb5be4c0834c24eee001, b2731fa1f8929c95734f2bbbb070fba54aad8c0b03c091841adcb5fa6f8e8101, 0509ac842f697683f93e4c90d7d586392a69e2b3617993d3c9d271fc8263400e, 89cca55611407966e14c6843369fd4fba929157e4fd905810b4e73b308b2fb0b, 20065cd958aed578e3e39f4d219321305769b2d469fef62edc058f31e8710105, 24a211f398f08e217e5346adbfc58d57048db940b3522580dc989ba57919100f, 00b23e562fd2d55ff8da6c6725cdbc9aa46c37237a44e1972e069aa38dbf9e0c, f5af0d4795562eb789f3a3b921222b255bf696f9c25e37ff6adae1dd69d5cb03]

$bbs1$ = [c7bb39bd54c2eb3c2732a54579a9ee49804d194775921e74ca5b2ba837cb7c06, cf6c5c588349462657283f468716baf291cfeb39d2a9b08432e258f720e49301, 05be98f7a1202133e6cc92cd6df0883abad9c5cb638500b09405a7209b15520f, 830dddeb1f9374974ffad80ef6e302473db9aae18343476009c6b7d92c22380e, 0737aefcc6dc2a3ed2bbe890f1d9b99c0cfdeef3133e7676eb91d2658b18f603, 9d9fd033cbae7dff8692ec4195720a37d503e0a0ee2a6c8918429e4fa6f46407, c4615fcbef48df920ff0f3c4cf14710b6ebad35456116fda951296c40b3ef80e, 7fb8364d65358c1022b96dccef7e695c85cad97d5d287c8e6c621ce310f82702, d3158d0c1fced1402a38c16666d94757096efa255bd4434fbbc7b2cb96d3990e, 406261c67dd480825da9f416964dcbd6ee714083b60ed3212a276660714b8509, c73ab316971d9d7a4e73cadd9a7c098ca93961dd041ee3bb596039cfb9a33003, 5327f82bb24dbba621efb8dafd47ff9ab51abb8be04e07c965d003662b2a8306, 48595ac0fce9c4ad84fa0225ddccfd2132a73e04783d246b73968d8c0e671f0e, 5eebd713b86a086d10a3b537e81d1d90b84b0d7f4a06bb8d63150a3a4fc4770e, 4046bfcdb7d56703f0738ecc6dd055172907d8cfdda8dcab3a991f377502850e, 3a4d82c50979a5fda8c37aad233e7795fc79641f7481d56d4808f275c278c10d, 52ddb63754e8ec2fe734a0a37b990ec61553b679c09496de7b98ba63771b4a00, d65b250db4c6e01c4f09c8b5a9d29817ed4aeee7bdf307a94a99d21d793a360b, 5e02423b61a4ca332f2bc284eb87830f338ce047b933e6fd12bdea6ca813b302, 402f4da9946865f50b24cb392b84a9d5136c1d4f14b745a16991b7918135ab0b, 8c0ffdf3626abc85a56fe7f187b8d9f486aeb080b04fc4f29d46d02d5a0b2e04, ad95282287763885e56dd95d84e72a4ae0957ef346111ce569ce63993cc71c07, 01ac55bb28d091965d51c94d1ed2e57f13efb6c9d4096b0e3a4ff7a4d2345902, 25478c14d10307f461a1e5816b762a9f0503ce516dac4682e39a6a275af1400a, 77fb99e40537764bed3f9a5f5dacf3b32b09b21bcbee1bab3ad7d728a56d9b0b, e1844b8b2c20c48988b10dbb86e5d559c37ee577e0f3901f31aeffb7bf9e6900, b70f978bf0f627816ab38510fd833a557ff7a5ccf320f3661f3b6eff81c98d05, 6f90a6096f775e2787a7569d363b419f511076a54a95fc5d99e8d8ea0a257f05, 0772879b24cca4a59e3130be2406cbea1c780fa2690c57a5f0510bcb287d9d03, 2c2a966b366d7222855a027a95578edc02fbe8070c40f117baf8bc59a157e80f, 83f4838da4115cbd5636eaf7a38f762bbfef48d3ddc4f924423aa23d96417c06, 391c69dadfa08ac3da6ec96d0ee1a64772a059eea76ae50b6ac3559f09321b08, a6799df3510f0025032901772bdd2acf1ac47be14870c155161e12125e4e530e, 2a1319832104dfadaee5facd19f38a8871bf8726b3ec47c3b393a22522cc7109, e142befd6b9957489e71d12d65f5f20f691175abed6160f886bbfbc9024cc507, 14d9eee48b4315f25c00044d022c581517ed97e7b5f70bd9c03f34c81cd2bd04, 3a5d025d5d6ac6d23ab5d898ad717f62f43d0a09dbbe6cc864cfa385041ed204, dcc9d94f8a61b6e53cb45eb48253e2d7e52e25da6bc4b5618e8fe28327c55607, c0e31aba5d2f238ca967d06ae8682d1e708290b678756fde561d59c764460b02, 379d5f9a073d7285603f9fa95dfabc1c7c7f51d9b9f5591e3a0bccb3ac164603, 9de5777b3852c4763a3553a71345b2a8150a93befa834da9cb40721f21d8b608, 8724efb2681b91b3f421999cfc9bba23cb6016bcb0e0f7e2fd05432ddc79c901, 43cdde500be65a136848df3fba2c922eb70db97a17e0d1994a92a92019d4680e, bafb5eb05fa0d7d29ca7869687d7ecff49cac52a4a01a969b34e5ad1320c3d0e, a6ee798251db9c39139bcf57bda27dbdc1fe7ea5d4bd5da7d99c647394e12501, c424e6f9543384fbcb974ce652d2f1b2ef43039aacc1feb05a3d7250b30c9305, 26ab33d9c6b9b5e2827c4edb2cff78962ed84a8bbfa3ecffc70c8d7412f6320f, d7cd5ce89751226ec5bb58370f61ff25fb561ba684bfc5af27c6c60d0b3f5708, 14ad48fe07d071ef83245419dfd88a69811999f56a37e65d1faf7213ecfd6f08, 096038635b9874ae87433688ac1e1df55cf08230af3f5cab6628ddbdcc91bd0f, dfca2946c8fc119bb2fdc4c3843a28233e4421d935bbabbd3cb7e22ad791120f, 81cad44be4d80a6ffc20811944d2bc52feaa81ee7a0faa5258eb84dcaf97c00a, 9fa767423588f4ac654d3c44fcf96fa1af180cab341a53dcce1ee221ba30af0e, 784b30a86bf5ae5a8abcaf8db1c5b33a167d7cc3dc3e46348da9ef5e10268c03, eaef95aac27effc18529365b4cf791ee0d6cde7192f122c13a739816704d2f07, 0f8d515c48c0400915d4ab0657b0646e85c558be46a696679198f1287189d209, 67626105070d831c1ba5a1d67ef047ac2a116f6bb4c7746d08c033d4f4781a0e, a2e0d3d5f2f9c1a40ef1180793c18946446a1ae798acebd5f5976fc59b03bb02, fac4c1c890db78040fce0372af2993f89556f1ce0f48dc0f1184809590c9ef01, ac1a20a802cdff3750b8840907ee28f097ed8533a02d5227cb0dae7f3d3e670e, 8b78dd8bce9f5eac29aaf1272411ddde7f1f99028f541ca018c408277d1a8406, a15c1da1ae11bb55cb6ce31a74c7d6751f21c4a9d0e83e6c73c7aaa381afbb0b, 1e661e0a7f7bfd20edb1b0faf894e57ced491b7f24b31c35b2b9ccafdf2fa808, 66556714d469501c193802970f3d2d4781d2396e459c34bd6101bfcd1d15860f]

Verification of Borromean ring signatures

Let's now verify if a Borromean signature is valid. The verification function is defined as: result = check_Borromean(C1,C2,bbee,bbs0,bbs1)

.

For $j = 0 .. 63$:

\[ \begin{align} LL &= bbee \, C1_j + bbs0_j \, G \\ chash &= \mathcal{H_s}(LL) \\ LV &= LV + chash \, C2_j + bbs1_j \, G \\ \end{align} \]

Finally we calculate $eeComp = \mathcal{H_s}(LV)$ and we subtract from $bbee$. If the result is 0, the signature is valid. \[ res = (bbee - eeComp) == 0 \]

The verification code is simply described by:

def check_Borromean(P1,P2,bbee,bbs0,bbs1,details=0):
    LV = ''
    str_out = '\n'
    str_out += '--------------------------------------------------------'
    str_out += '\n'
    str_out += 'Verifying Borromean signature'
    str_out += '\n'
    for j in range(64):
        LL = bbee*P1[j] + bbs0[j]*dumber25519.G
        chash = dumber25519.hash_to_scalar(str(LL))
        LV += str(chash*P2[j] + bbs1[j]*dumber25519.G) 
        str_out += str('LL = ')
        str_out += str(LL)
        str_out += '\n'

    eeComp = dumber25519.hash_to_scalar(LV)
    str_out += str('eeComp = ')
    str_out += str(eeComp)
    str_out += '\n'

    res = (bbee - eeComp) 
    str_out += '\n'
    str_out += str('Result: ')
    str_out += str(res) 
    str_out += '\n'
    str_out += '--------------------------------------------------------'
    str_out += '\n'

    return res == Scalar(0), str_out

Taking the same parameters as described in 'Generating Borromean signatures', we can see that this signature is valid by running the above code:

--------------------------------------------------------
Verifying Borromean signature
LL = a0c9c09415751f95a9279aec1c4dcb98b014b8cacc96147d56e6315025ab8a7f
LL = 260aa32dfb0acdbc8c049a1765b62588754a3f78555645dac43ea3e5790383ab
LL = c204241585207be3c44adba1b818e1330bed37c3ff60de88de9e48f08fc24d9b
LL = cbf81914dced1c61919df14ea3b8402a52597e72e6659104c63f86556dfe0c46
LL = 2be4f6bb954c7c18e639f216ba34db4bf9c3d64ad98cabff4915b8dd514916b5
LL = 296f82f03fa47d0fd0da67fa47acf2156c4a0ac89fde060b0a905e17e2646a2c
LL = 8d9ef0e1c621e8ff4015309859ae612f05e43e4f5e02fdf81ec0a1a320c748d7
LL = 418706645ec33a13332532e867565d4d86e650acf8e858c6694bb4d5a20529db
LL = 124b9f54bf06efedbf425c0f8b7b1f5188824ac223c27c5dd76729e1f975f772
LL = cf3acd39685816c157f588b00d8b7f623ba3255868c98700e82db25e09008b6b
LL = 244b9a2ec51e39e57b88b1f41d6101b0d3582ac369a737e91397d156be89d1e8
LL = f3a946785fd9840c9d5fe31e4bc458e9357f79ecd2be19faae4032e4b001a589
LL = f31d416085d0994d0f4444cd6844f9fe0e9c30b6ae9357055dadaca512fd1c22
LL = dbc9ee8b9d4b83fd460d0f42d551aa7e78f43a6b7c4438dfea8bf4f5a702713f
LL = 80ea8ea0f31b381a7be5107f0e020d8f3e8eedf2f9d3b07b3ecade3c1970f7ca
LL = 4ed2f3facef7775245790e3684c921c42034689656482d42539fb4920e8164f1
LL = bf51ad0ec2cbbe1ce3a3bea2b74be70359dc23b081599a8e3a3496f83bfdb078
LL = b010c7b220d1bdb100079e97b6261ab04b38f32a3f182051f4611c9e6f43db35
LL = 0d54e2bc01867e989bc97d5c6989cd2914a81efa2c49600bc738da2b35f082d0
LL = a2809adaf0f5fa61fded1643b921bfe261ef4ee929136c1e8c768523a9a80174
LL = dfa48e0752cfe032788f076aef9bfb627a30af1f5fb35f20e167c0933cd4cc37
LL = b027b356c13126cb94ea00666f3fccf51a10ef5de45d15b4eafe4826322ac915
LL = 19e05233babff2f4d9890f5a4c2eb13fc0a91da4dad864542200779a4c8b5d60
LL = 74c12b248739552aed86077e8c9dd880814c5f6ec8faaa9a8c4f50f639e56467
LL = cd789791230de42abe4a2c2be57d8af0f082916e0bbc0b32c716655e928ea253
LL = 07d25c1b725c2189a1541f9948963f1b2d9159bf48cd25ad64de741250e2cba1
LL = 05664dc0269c7b7d4adeb706d75c5b1154196e521945ce14f09d76dd72eeefee
LL = b38f96c5c0b565ea03b5ee1d90f48e1315ff6f63938a46437c1cdba20e46edb3
LL = f5a83928858cd3291fa199ffdff02727e7c05ef989c0b743b615518a656f53f0
LL = 5237b64deb2b296e192540e292414fb3d98ababd831487dab99141b36d685245
LL = e711defab48d5bd46caf9478ed0e65baf520c5dd6ba9c28400b37daaa16fd524
LL = b7246b96525284d6f72099f80f4f0278d33090b037353dbe396f4b0e88c00bc0
LL = 34cfe11c5a4a4256f341b5c0243239262181230c117250ed3094a196ce758184
LL = 0ab7b1cd4f40129b55eeed4df54dff3d6be42f4aa3bb88b6a964605586c0b737
LL = eedd454da6af2d1ba131b230755344f9b58380a1ed888ffca1f39a4f9197d97c
LL = b226d4dce8afb63b17dd81d4f2a725a6b8c2d891336f0d09dbf711be60109ad6
LL = f1367a82e9380af84bcce258f2c435515b5d6f17b22e70c11d19f17700d7b0cb
LL = 662a3b5c3e7c9b2890b3186854ddef23e2506304c61155692242bd9354dc56a8
LL = 525e184063f3abd887eb708dbd300a0070c2037486d78930c60757ee21169526
LL = a970fbd179ce10eec691118376a559390251856f566e5c916def1e8a5c075620
LL = 7f7f82044a9e4cf64cb746ffeada7dbf6fb6ff2f5cd6db325d31eb965c02076b
LL = cc516e8c7dd8703233f75e9ddc220a61427653c1cdfc74bd09822f064f515f1e
LL = 7aed9d97eea71edb1bff501fe78f16179fc016127f3699eed67fd35f2a0ca8c2
LL = e7f58442de2838f699c3e3a37deee78983935838812d8413d922b121b66cf988
LL = 49f073171ce288a2ce2cec790979c7130ec78313bfb0a0a5fd7555b1f47e99dd
LL = 415efe2e73ac2c05634dfd4591c2328e12f9c08e28a136abd6b026e20f60618d
LL = 684e3d7572508a5c843c9332da17346fda9446939ee73c31477b07603cd77238
LL = f044674a0fd8bc8d68533fc9d35c4004d9a071668b11eb00e67cd282d77fcfe9
LL = 91ba4bf638bd973dc124c5ec21e851c222c798b9ba7c1a15331b9fc405b88015
LL = 9847353a807ec21e7ee38928f2b239594019dba6446bbd42adee02e83266c148
LL = f6e0a8f1e0651209d14d7486b4e13d2239e8d56e0e438bd03833452201d1f708
LL = 7dc948897956b40352aa034c06e3ba84c3bd94ef2f7a93c625c38af5a3af95f9
LL = 6200742602ce4bfe1ada922123bf2d7f4ce40ce86026317a5c869e776c379618
LL = 0f5f604c4d7e97285b82c5bd0c3f4a6cb49b84a5736d2c2cbf5da1fb7a92a713
LL = f507399875ec4cfc91940985da6011edc0b5a4c71440fbda34548bd52deb7df6
LL = 7260c40cf6d016da392e17c3256f3c73bfca28bfefd66ce9b061a55e5f315394
LL = 0d1448b1784574b1727f08d1916fa6a8f144c5cfc75f4843de795d3682e13379
LL = 96335565769db7a448e1ba7fd50b6aa44303d17aab4765edb2363af18ddb82e9
LL = 48eab94e2bdeb6fb97b4d73c316b4a9b81e379f16097cc7b350dc65fec26ae5d
LL = 80579032d88f4ae76d0cf66d5e1b140ddcb0aa3704ae0cef915166a102edd101
LL = ecb47474f35348fc9cd719a2a16fc2aff747c45a6ccaafd10fd2ad9e5e064271
LL = b2ea8ddded1444ca161dbe626771be864e7b769c89e5dd63a4809eb67d118519
LL = 74f7bf498251cc67f799d7a2be0db30f7ab41d553fa9ab136d1a49b09ef6e52b
LL = 25474c428823192c77de497693c4d460b162b0382675fdb31c20d240af13b733
eeComp = c5c5fc225bf23729012e099446c40bded061dae53782cae16c46102a042b8808

Result: 0000000000000000000000000000000000000000000000000000000000000000
--------------------------------------------------------

RCTTypeNull (version = 2, type = 0)

This is a miner transaction, it has one input, which is the height of the block, and outputs containing the addressess and the reward value. The amount has to be lower than the specified agreed value of the emission curve and it is not hidden. An example is found here.

RCTTypeFull (version = 2, type = 1)

This type of transaction was conceived to be more compact. It has one input and many outputs. We can prove that the $inputs = outputs + fees$ by looking at the structure of the 'Commitment' member at the MLSAG signature scheme. We have to prove that the input commitments are equal to the output commitments plus the fees, as the commitments are homomorphic. Let's call the input commitment $C_a = xG + aH$, the sum of the output commitments $\sum C_b = \sum (yG + bH)$ and the fee commitment $C_{fee} = fH$. Therefore, we have: \[ C_a = \displaystyle\sum_{i} C_b + C_{fee} \] We can obtain $C_a$ directly by looking at the commitment of the output that we are trying to spend from. It is located at the field 'mask' when an output is stored in the blockchain. We would of course also know the amount and blinding factor as we own this output. The output commitments are built by the sender who is constructing the transaction, he chooses all of its parameters (blinding factors and amounts). Finally, he has to add the fees and choose the appropriate output blinding factor $y_m$ of the last coefficient in order to match the equation above. This can be done by picking the appropriate blinding factor as shown below. \[ y_m = x - \displaystyle\sum_{i=1}^{m-1} y_i \] Now, if we can sign the transaction, by proving that we own the private key $z$ corresponding to the public key of the commitment ring member, as shown below, then we can be sure that the equation $inputs = outputs +fees$ is valid. We know that the commitment ring member is defined as: \[ PK[i][1] = \text{get_outs(key_offsets[}i\text{])["mask"]}-(\sum \text{outPk}) - fee*H \] In other words, it can be represented as: \[ PK = C_a - \displaystyle\sum C_b - C_{fee} = xG + aH - \sum_j^m (y_jG + b_jH) - fee H \] If the amounts cancels out ($a = \sum_i b_i + fee$), as expected in a transaction, then we have for the commitments: \[ xG - \sum_j^m (y_jG) = zG \] Where $z$ can be written as: \[ \begin{align} z &= x - (y_1 + y_2 + ... + y_{m-1} + y_m) = x - (y_1 + y_2 + ... + y_{m-1} + (x - y_1 - y_2 ... - y_{m-1}) \\ z &= -2 (y_1 +y_2 + ... + y_{m-1}) \end{align} \] Therefore, if we can sign the transaction with the private key $z$, then someone observing the blockchain can be sure that there is no inflation happening.

RCTTypeSimple (version = 2, type = 2)

This type of transaction was conceived to be more generic. It has many inputs and outputs. In a similar way as the RCTTypeFull, we can prove that the $inputs = outputs + fees$ by looking at the structure of the 'Commitment' member at the MLSAG signature scheme. We have to prove that the input commitments are equal to the output commitments plus the fees, as the commitments are homomorphic. The difference here is that we have more than one input and we cannot use the previous commitment of the output that we are trying to spend from. We will need to create 'Pseudo outputs' in order to verify the amounts, therefore, there will be an intermediary step. Let's call the input commitments $Ca = xG + aH$, the pseudo commitments $Ca^` = x^`G + a^`H$. We know that the commitment ring member is defined as: \[ PK[i][1] = \text{get_outs(key_offsets[}i\text{])["mask"]}-\text{pseudoOuts} \] In other words, it can be represented as: \[ PK = Ca - Ca^` \] Therefore, we have: \[ Z = Ca - Ca^` = x G + a H - \left( x^` G + a^` H \right) = z G \] If the amounts cancels out ($\ a = a^`$), as expected in a transaction, then we have for the commitments: \[ \ (xG - x^`G) = zG \] Where $z$ can be written as: \[ z = (x - x^`) \]

Now, if we can sign the transaction, by proving that we own the private key $z$ corresponding to the public key of the commitment ring member, as shown above, then we can be sure that the pseudo outputs corresponds to the value commited at the output that we trying to spend from. It does not prove though that that the output values of a transaction are obeying the equation $inputs = outputs + fee$. Let's see how we can do it.

Up to now, we did not speak about the commitments of the outputs that we are creating, let's call them $Cb = yG + bH$ and let's suppose that we have $t$ outputs. Therefore, the sum of all output commitments can be written as: $\sum_{j=1}^t Cb_j = y_jG + b_jH$. Similarly to the RCTTypeFull, we can chose the coefficients of the pseudo output commitments to match the blinding factors in order to prove that there is no inflation happening by proving that the amounts cancels out. (If they don't, it means that we found a relation between $G$ and $H$, which is as hard as solving the discrete logarithm problem).

So, let's verify that $inputs = outputs + fee$ by verifying its commitments, where $m$ is the number of inputs and $t$ is the number of outputs. We have:

\[ \displaystyle\sum_{i=1}^m Ca_i^` = \displaystyle\sum_{j=1}^t Cb_j + C_{fee} \\ \] This equation can be simply verified as all the commitment values are explicit shown in a RCTTypeSimple transaction. Therefore, if this equation holds, then we can be sure that there is no inflation happening. Similarly to the RCTTypeFull, the create of the transaction will choose the m^{th} pseudo output term to be as: \[ x_m^` = \displaystyle\sum_{j=1}^{t} y_j - \displaystyle\sum_{i=1}^{m-1} x_i^` \]

Let's create money out of thin air, why not?

Suppose that we received an output $K_o$, we know its private key $k_o$, the amount $a$ and the blinding factor $x$. It means, we know everything in the equation $Ca = xG+aH$. Let's also suppose that a = 0.3 XMR. Now, I would like to spend my 0.3 XMR output and buy a car with it. Unfortunately, I don't have enough money as the cars here cost 30 XMR so I will try to write two zeros in front of my 0.3 XMR 'bill' and see what happens.

First step

I need to create a commitment to my new value, let's call it $Cb = yG+bH$, where b = 30 XMR.

The blinding factor $y$ is related to the amount by the range proofs, so let's try to create this new commitment otherwise anyone verifying the Borromean signatures would discover that the commitment $Cb$ does not correspond to $b$.

Let's get the binary representation of b.

\[ b = b_02^0+b_12^1+...+b_k-1^{k-1} \]

Now we generate random numbers $y_i$ and we store the $C_i$ generated by:

\[ C_i = y_iG + b_i2^i H \]

Now, we want to prove that the sum of all $C_i$ is equal to $C_b$, which means:

\[ \displaystyle\sum_{i=0}^{k-1} C_i = \displaystyle\sum_{i=0}^{k-1} y_iG+b_i2^iH = yG+bH = Cb \\ \]

and this will only be true if the following holds:

\[ y = \displaystyle\sum_{i=0}^{k-1} y_i \]

As the $y_i$ are randomly generated, and we proved using the Borromean signatures that they are either the private key of $C_i$ or $C_i - b_i2^iH$, we have proved that $y$ corresponds to the real value of $b$. If the Borromean signatures have failed, I would not be able to prove that my blinding factor is actually blinding the real value of $b$ and I would be witnessing an attempt of forgery here.

Second step

Now, I have my commitment $Cb = yG+bH$ with b = 30 XMR. Let's try to sign a transaction with this amount.

We have two possibilities to sign a transaction, either using the RCTTypeFull or RCTTypeSimple schemes.

In the first case (RCTTypeFull), I will need to prove that I know the private key of the public key defined by:

\[ PK = Ca - Cb - C_{fee} = xG + aH - yG - bH - fee H \]

As the amounts do not cancel out ($a = 0.3 \neq b + fee = 30 + fee$ ), as the fees cannot be negative, then we will have a factor depending on H in the equation of the public key. Therefore, we would need to have a private key $z$ correponding to:

\[ (x-y)G +(a-b-fee)H = zG \]

As we do not know $z$ as we would have to solve the discrete logarithm problem to get a relation between $G$ and $H$, then we would not be able to sign this transaction and the ring signature would fail.

In the second case (RCTTypeSimple), I will need to prove that I know the private key of the public key containing the pseudo output commitment and defined by:

\[ Z = Ca - Ca^` = x G + a H - \left( x^` G + a^` H \right) = z G \]

We could create some pseudo output commitments that commits to 0.3 XMR being spent, otherwise the ring signatures would fail. If we commit to 0.3 XMR, then we would have to pass the last check, which is verifying if the equation $inputs = outputs + fees$ is valid. Which means, verifying:

\[ \displaystyle\sum_{i=1}^m Ca_i^` = \displaystyle\sum_{j=1}^t Cb_j + C_{fee} \\ \]

As we tried to cheat, the amounts won't cancel out as $0.3 - 30 - fee \neq 0$ and there will be a remaining term depending on H. Therefore, it won't be possible to find the term ($x_m^`$) (as we would have to solve the discrete logarithm problem to find the relation between G and H) and this verification would fail.

\[ x_m^` = \displaystyle\sum_{j=1}^{t} y_j - \displaystyle\sum_{i=1}^{m-1} x_i^` \]