Skip to content

Instantly share code, notes, and snippets.

@coranos
Last active May 11, 2021 14:51
Show Gist options
  • Save coranos/9cdd2074ebe5c4a94cee1787accaee38 to your computer and use it in GitHub Desktop.
Save coranos/9cdd2074ebe5c4a94cee1787accaee38 to your computer and use it in GitHub Desktop.
Camo Banano - Private Coins on Banano using ECDH.

Camo Banano

Private Coins on Banano using ECDH key exchange.

by Coranos

camo banano consists of three layers of technology:

  1. blockchain steganography
  2. storing ecdh public key in the blockchain 3.a. private reversible transactions, using shared seeds. 3.b. private irreversible transactions, using shared public keys.

starting state

it is assumed that each party in the transaction has an existing seed with an existing wallet.

the whole purpose of this system is to send funds to the other wallets on a given seed knowing only the first wallet.

so the parties are in control of the funds but do not show up on a rich list.

blockchain steganography

Since the banano balance has a precision of 29 places after the decimal, you can store 11 bytes of data in the balance field.

since the representative field is only needed for voting, you can use it to store 32 bytes of data.

storing ecdh public key in the blockchain

the ecdh and EdDSA public keys derived from the same private key are not byte-identical.

so the ecdh public key must be stored in the blockchain.

to do this, we split the 32 byte public key into 3 chunks of 11, 11, and 10 bytes and send three transactions to ourselves encoding these bytes in the balance field.

to help is find the data later, we also change the rep to the blake hash of our public key. it is unlikely to be a real rep, and the low vote weight wont matter much anyways.

private reversible transactions

the ecdh public keys are used to create a shared secret.

the shared secret is then hashed once, so its more uniform.

a new seed is created, never used before. that seed is stored in the blockchain in a simmilar way as the ecdh publick key. first you xor the hashed shared secret with the new seed, then you split the seed into three chunks, then you send transactions to yourself to store the seed in the blockchain. in this case the representative is set to the hash of the shared secret, to help find the data.

once both parties have the shared seed, transactions are 'reversible' because both parties can spend the coins as they both have the seed.

private irreversible transactions

using the same method as reversible transactions, a new wallet is created instead of a new seed.

the new wallet is controlled by only one party, so transactions are not reversible.

that new wallet is stored on the blockchain in almost the same way as the reversible seed. the only difference is that the rep is set to the hash of the hashed shared secret and the public key, to distinguish it from the reversble transaction.

mixing

It is possible to use camo to create a mixer, though this is not trustless. Every day the mixer creates a new seed, never used before, and uses it as a hot wallet. You send reversible transactions to the mixer address. The mixer puts one or two transactions into the hot wallet. The mixer sends reversible transactions back to you. The mixer destroys the new seed.

Now assume the mixer is compromised, it's seed is exposed.

  • it will be possible to trace who sent inbound transactions to the mixer.
  • it will be computationaly intensive to trace outbound transactions, as the hot wallet consolidates all inbound transactions, so as long as there is sufficient volume going through the mixer.

false transactions

When making a transfer, it is useful to have several fake transfers made as well, so a third party cannot do timing analysis. This would require the sender to make 1-N transfers to himself, as well as the 1 transfer to the reciever with the same amount.

@coranos
Copy link
Author

coranos commented Oct 26, 2018

im storing the key in the blockchain.

@coranos
Copy link
Author

coranos commented Dec 15, 2018

@inkeliz so it turns out it's slow to store the key in the blockchain (takes 3 blocks, so 3 round trips)

So I'm revisiting your suggestion. I'm using Java, and the best X25519 implementation I found was https://github.com/google/tink

I don't see a public key to public key conversion, do you know of any pure java implementations of this feature? Or just in golang?

@brunoerg
Copy link

@coranos
Copy link
Author

coranos commented Jun 28, 2019

Turns out I found another solution, using javascript, and have implemented it:

https://coranos.github.io/bananos/camo/

@brunoerg
Copy link

brunoerg commented Jun 28, 2019

Isn't https://coranos.github.io/bananos/camo/ open source? I didn't find the source code..

@coranos
Copy link
Author

coranos commented Jun 28, 2019

You serious, you can't find the source code to a webpage?
Control + U.

If you want it as a git repo, the source is here:
https://github.com/coranos/coranos.github.io/tree/master/bananos/camo

@brunoerg
Copy link

Just asking for a repo to contribute! don't worry!

@coranos
Copy link
Author

coranos commented Jun 28, 2019

Ok cool. If you think it's worth something I can pull the page into it's own repo.

The meat of the code is also in bananojs.

https://github.com/coranos/bananojs

Instructions on the commands are in the readme.

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