Request for Funding @scilio (CoinSwap Implementation)

That’s not the onion encryption that the design calls for.
The payload for node i should be encrypted so only node i can decrypt it, which should result in the data for node i + the payload for node i+1.

With your vector of payloads, the first and last nodes could collude to correlate their data.


Given 3 nodes n1, n2, and n3, each with known pubkeys n1.K = n1.k*G, n2.K = n2.k*g, and n3.K = n3.k*G, the caller provides

* ephemeral_key: The initial ephemeral pubkey, R1
* commitment: The real input commitment C0
* payloads:
    1. E1(p1)
    2. E1(E2(p2))
    3. E1(E2(E3(p3)))

n1 then computes shared secret s1 = ECDH(n1.k, R1). Using s1, the node decrypts the 3 payloads to get p1, E2(p2), and E2(E3(p3)). It reads the excess x1 from p1.

n1 then calls n2 with

* ephemeral_key: R2 = BLIND(s1, R1)
* commitment: C1 = C0 + x1*G
* payloads:
    1. E2(p2)
    2. E2(E3(p3))

n2 computes shared secret s2 = ECDH(n2.k, R2). Using s2, it decrypts the 2 payloads to get p2 and E3(p2). It reads the excess x2 from p2.

n2 then calls n3 with

* ephemeral_key: R3 = BLIND(s2, R2)
* commitment: C2 = C1 + x2*G
* payloads:
    1. E3(p3)

n3 computes shared secret s3 = ECDH(n3.k, R3). Using s3, it decrypts the remaining payload to get p3. It reads the excess x3 and rangeproof Π.

n3 computes the final commitment as C3 = C2 + x3*G and verifies the rangeproof Π.

This can be seen in action in this test I wrote.

1 Like

It seems like you have n*(n+1)/2 decryptions in total which is of order n^2 instead of exactly n. Couldn’t n1 decrypt only the 3rd option and get p1 along with the next encrypted message? The encrypted payload would need a recursive form:

Payload {
  rangeproof: BP | None
  private_excess_share: x_i
  encrypted_data: Payload | None

It doesn’t actually involve more decryption. It’s a stream cipher, so whether we perform the decryption on the whole chunk at once, or decrypt each payload individually, the same amount of processing is required. You can think of the payloads as being one contiguous block of data instead of separate blocks in a list, and you’ll see that, in practice, it’s exactly the same as what you’re proposing.

btw, I chose to model it from the onion routing standard for lightning.


The commitment should not be separate, but there should be one in every payload, so the node knows which excess to apply to which commitment. This looks like a major oversight.

Ok, so that is essentially equivalent to using the intended

E1(p1 | E2( p2 | E3(p3)))

The excess is in each payload. Why does the commitment need to be there also?

Under data provision of your design, the inner nodes j ∈ {2...n-1} are to be provided with

  • commitment Ci,j-1
  • excess share xi,j

Since Ci,j-1 is actually calculated by node j-1, I don’t understand why we would need for it to be part of the encrypted payload.

1 Like

Because, as the proposal states:

Each node receives a sorted column, not knowing the i indices shown,
transforms each commitment by some excess specified for that commitment,
sorts the results, and passes on the new column to the next node.

To prevent correlations, node j must not know which commitment belongs to which user. That’s why the payloads are permuted by each node.

It’s a little worrying that you missed the essence of the design:-(

If there’s any aspect of the coinswap protocol that’s not entirely clear to you, then please ask for clarification, so we don’t have such misunderstandings.

Node j still won’t. For each i, a Ci,j-1 is computed by node j-1. The tuples (Ci,j-1, payloadsi,j) are then sorted by commitment (Ci,j-1), and the sorted matrix of tuples is then sent to node j. Node j+1 wouldn’t see Ci,j-1.

The design is clear to me. I believe we’re just speaking on different wavelengths :smirk:. I’ll finish writing the RPC layer and then take a break to more formally document the flow of data. That should clear up any misunderstandings.


I’m sorry for mistaking your deviation from the proposal as a misunderstanding. I now see that it’s a useful optimization.
My apologies, and good job on spotting the redundancy!


Milestone 1 is just about complete. I just have a bit of error handling left and some documentation to write. If someone could create a mwixnet repo in the mimblewimble github org, I’ll be able to create a pull request for everyone to review.


Repository created GitHub - mimblewimble/mwixnet: Implementation of the Mimblewimble CoinSwap proposal.


Thank you. I’ve created the pull request.


I think we need to come up now with a review process in order to accept the first PR.
Great work and now we need a community effort to review the PR.

Who would be able to review it?
@tromp @joltz @davidtavarez


I will do my best to give it a review this week.

First I need to familiarize myself with the protocol we are trying to implement. Is Mimblewimble CoinSwap proposal the completed specification or is there an updated one somewhere else?


The code is based on that design, with some modifications documented in the README


@scilio could you give an update on the 18th Agenda: Community Council (CC), 18 January 2022 · Issue #33 · grincc/agenda · GitHub . If you’re unable to attend could you leave an update on the forum?

1 Like

This post was flagged by the community and is temporarily hidden.

Milestone 2 is nearing completion. So far, it

  • communicates with a GRIN node’s API using jsonrpc calls
  • validates input signatures using the new Commitment Signature scheme
  • verifies input commitments are in the UTXO set
  • executes round every DAY_HEIGHT (1440) blocks
  • verifies generated output commitments are not in the UTXO set
  • builds the kernel and assembles the transaction
  • submits the transaction to the node

For milestone 2, I still need to

  • add reorg support
  • improve fee handling & wallet support (could fall under milestone 3)
  • add better e2e tests

Trying to add support for handling reorgs efficiently has been the main challenge so far. I’m getting frustrated by the lack of progress, so may skip this and come back to it after the rest of milestone 2 is finished and merged.

My original time estimates were apparently too optimistic. Estimating software is hard. But don’t worry, I’m not going anywhere. I’ll try to give more frequent updates so everyone knows I’m still here.


Thank you for the diligence and excellence, Scilio.

Glad to hear that. I’ll take this opportunity to remind about some minor checks that would still need to be done about duplicate inputs/outputs which would stall the process that we left here for the next one.

1 Like