Skip to content

Instantly share code, notes, and snippets.

@phyro
Last active October 12, 2020 19:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phyro/22be7833265a4448eb3815ff8ae8c4de to your computer and use it in GitHub Desktop.
Save phyro/22be7833265a4448eb3815ff8ae8c4de to your computer and use it in GitHub Desktop.
Tx obfuscator

Transaction functions

Tx Aggregator

We are all familiar with transaction aggregation, it's a process of taking two transactions and aggregating them to create a new transaction. Given a transaction T1 and a transaction T2, we can apply an aggregate function on them aggregate(T1, T2) -> T3 to obtain a new transaction T3. The good property it has is that T3 has a higher anonymity set which is what we want to achieve. What it does not do however, is that if you have seen T1 or T2, then you still know which outputs are linked together. Aggregation can't unlink previously obtained knowledge regarding output links.


Mimblewimble flexible transactions

There is a possible way to potentially unlink previously seen links between the outputs. We will use a property that is unique to Mimblewimble which is that transactions don't commit to inputs and outputs, but rather only on the difference of their sums. This means that our inputs and outputs are never really sealed. Given a transaction T where we own and input I1 and an output O2, we can replace both of them with arbitrary many inputs and outputs (including none). We can do that by calculating the difference between the blinding factors that is needed in order to keep the transaction valid and we do that by adjusting the kernel offset accordingly. I've been referring to this as output swapping. It doesn't seem useful at all because only the owner can do it. Moreover, if the owner shares the information on how to swap the output with others, they know what was swapped so it seems as if it can't be used at all.


Tx Obfuscator

Let's ignore for now how the transaction data below is collected and let's just assume the data is received. Given a transaction T with an output set S, and a description of output swaps for each output, anyone is able to produce a transaction T' with a completely different output set S'. Any knowledge about links from S can't be useful if others have not seen the S -> S' mapping. I refer to this as a transaction obfuscator, because it removes all the outputs and creates new ones. The question is how do we communicate this data in a way that could improve privacy.

In theory, if we had a chain of nodes where each node would be given a pair (T, output_swaps), then we would end up with a chain where the transaction outputs get completely replaced with new ones at each move:

Node1(T) ----T'---> Node2(T') ----T''---> Node3(T'') ----T'''---> NodeF(T''') ----T''''---> broadcast

Note that Node3 would be given (T'', output_swaps) where output_swaps describes a mapping T'' -> T'''. The question now is where can we find such a chain.

Objective Dandelion Obfuscator

Objective dandelion defines an objective path towards a node that broadcasts the transaction. It's defined as a max function over the peers you're connected to. If you're the max peer in your neighbourhood, then you're refered as the fluff node. The purpose of this is to funnel transactions to a common point in order to increase the chance of aggregation. For simplicity, we will ignore the details of the idea. Given a starting node in objective dandelion Node1, we have a clearly defined path to the fluff node NodeF:

Node1 ----> Node2 ----> Node3 ----> NodeF ----> broadcast

We could ask Node1 to tell us the path to NodeF because the path won't change. Node1 would compute the path by recusively asking the same question to Node2 and adding itself to the path result. If each of the nodes generates a public key per epoch, then they have an identity. This means that we could ask for a path of public keys. We now have everything we need to produce a pair (T, output_swaps) for each node in the path. The sender and receiver need to agree on the starting node of the objective dandelion, obtain the public keys on the paths create an onion encrypted output swaps in a way such that a node receives (T, M) where M is an encrypted message which can be decrypted by the node's private key to obtain a pair output_swaps, M'. The node performs the output swaps to obtain T' and send a pair (T', M') to its max peer (the next node on the path).

Node1(T) ----T'---> Node2(T') ----T''---> Node3(T'') ----T'''---> NodeF(T''') ----T''''---> broadcast

So only Node1 knows the mapping from T -> T', only Node2 knows mapping from T' -> T'' etc.

When T'''' is broadcasted, nobody knows how they map to the original outputs that have been created (except the owners).

A node on the Objective Dandelion path does not could be used not only as an aggregator but as an obfuscator as well. A combination of increasing anonymity size and forgetting the history could be a possible path to think about.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment