Author

Topic: Jumblr - decentralized bitcoin mixer with 0.1% fee (Read 4112 times)

newbie
Activity: 41
Merit: 0
https://soundcloud.com/coremediaradio/jumblr Here is the latest on Jumblr fellas
legendary
Activity: 1176
Merit: 1134
But then you trust the initiator of the shuffle to not be an attacker himself. If he occupies the first k spots, it is as if the shuffle starts from k+1. At least in the Nxt core implementation, the shuffle creator is equal to all other participants, and will be penalized the same way if discovered to cheat.
I think in all variants the assumption is that there are non-attacker nodes participating. if the attacker is a passive statistics gathering attacker, i dont see how anything can be done to prevent (or even detect) such info gathering attackers

But if you control, the first two slots and assume at least one other non-attacking node, at least the initiator will get some privacy.

It would be interesting to see the math on how many shuffle rounds are needed to obtain practical privacy. I am thinking at least 10. Assuming there are 100 nodes ready to shuffle, then by making 10 random groupings of ~10 nodes to shuffle with, unless the attacker controls the majority of nodes, it seems to gain privacy.

James
sr. member
Activity: 392
Merit: 250
But then you trust the initiator of the shuffle to not be an attacker himself. If he occupies the first k spots, it is as if the shuffle starts from k+1. At least in the Nxt core implementation, the shuffle creator is equal to all other participants, and will be penalized the same way if discovered to cheat.

I have all parts of the algorithm implemented and working now, including the blame phase of detecting and penalizing rogue participants who either submit invalid data or do not submit their transactions in time, with all integration tests passing. What remains is only to make the shuffle process user friendly, by automating the submission of process/verify/cancel transactions.

For the AES encryption, I now use GCMBlockCipher:

Code:
    public static byte[] aesGCMEncrypt(byte[] plaintext, byte[] key) {
        try {
            byte[] iv = new byte[16];
            secureRandom.get().nextBytes(iv);
            GCMBlockCipher aes = new GCMBlockCipher(new AESEngine());
            CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
            aes.init(true, ivAndKey);
            byte[] output = new byte[aes.getOutputSize(plaintext.length)];
            int ciphertextLength = aes.processBytes(plaintext, 0, plaintext.length, output, 0);
            ciphertextLength += aes.doFinal(output, ciphertextLength);
            byte[] result = new byte[iv.length + ciphertextLength];
            System.arraycopy(iv, 0, result, 0, iv.length);
            System.arraycopy(output, 0, result, iv.length, ciphertextLength);
            return result;
        } catch (InvalidCipherTextException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }
legendary
Activity: 1176
Merit: 1134
@timruffing:

On the attack vector with the second and last positions occupied by the attacker. The fact that the initial node is only sending its own vins/vouts seems to create this attack, but of course this streamlining of data offers a lot of speedup.

Anyway, I have an idea to avoid this attack. Why couldnt the initiator of a shuffle occupy the first two spots? this would protect the first node from the 2+last attack wouldnt it? Granted if the attacker is in spot 3+last, it would still leak information, but at least there are two possible accounts and by making one of them like the change outputs and not expecting additional privacy, maybe this will reduce the attack?

Alternatively, what do you think about all (more?) nodes sending their vin/vout to the first node? That would seem to totally thwart the 2nd+last attack

James
legendary
Activity: 1176
Merit: 1134
Okay, my point was the other way: I assume it's not obvious that it is okay to give out the secret key. Indeed, if you look at the description of NaCl, the security model section (http://nacl.cr.yp.to/box.html) and the referenced paper do not claim that the message stays secret in a situation where the senders's secret key is known, even if the recipient's secret key is not.

Still, publishing the sender's key seems to be for that NaCl scheme, and everything else would surprise me, but I haven't looked at it in detail...
OK, it seems safer to just use GCM mode of AES using standard shared secret with a onetime sender keypair

Thanks for the feedback.

James
legendary
Activity: 1218
Merit: 1006
What actually is the mixer means? As i haven't heard this before so i came to this thread but after reading all post i can't get any clue about what the mixer is actually. If anybody don't mind to explain me can you?
Mixer is essentially this
1) You send bitcoins to an address(from the bitcoin mixer service)
2) After the payment is recieved in the address, the service sends you your btc to your 2nd address through a completely random address.
Of course this is just the simplified version of it, most mixer noawadays provide many customizations for added privacy. As as you can probably guess, people do it to hide their tracks that people can track through their transactions.
Thanks for good explanation brother. Maybe i will also try to giveaway bitcoin payouts from my site.
newbie
Activity: 14
Merit: 10
Actually, I don't think we use AES in authenticated mode, here is how it is called, using the BouncyCastle library:

Code:
    public static byte[] aesEncrypt(byte[] plaintext, byte[] key) {
        try {
            byte[] iv = new byte[16];
            secureRandom.get().nextBytes(iv);
            PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
                    new AESEngine()));
            CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
            aes.init(true, ivAndKey);
            byte[] output = new byte[aes.getOutputSize(plaintext.length)];
            int ciphertextLength = aes.processBytes(plaintext, 0, plaintext.length, output, 0);
            ciphertextLength += aes.doFinal(output, ciphertextLength);
            byte[] result = new byte[iv.length + ciphertextLength];
            System.arraycopy(iv, 0, result, 0, iv.length);
            System.arraycopy(output, 0, result, iv.length, ciphertextLength);
            return result;
        } catch (InvalidCipherTextException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

Hm, the security argument depends on the fact that the whole encryption scheme is IND-CCA secure, and CBC does not ensure that. I have even a concrete attack idea with CBC in mind but that would require some additional thinking... (and I prefer to think about countermeasures. Wink ). The general problem is similar to the one with the duplicates. Instead of just duplicating a ciphertext, P2 can try to duplicate and change it such that it decrypts to something similar not exactly the same plaintext. Because it is not exactly the same plaintext, the duplicate check does not help here. A later peer then sees that there are two related plaintexts.
IND-CCA provides exactly the property that you cannot change the ciphertext in a meaningful way. If you try to change it, it does not decrypt at all (decryption error) or it decrypts to garbage, which is not related to the original plaintext anymore. 

Note that the signing that you've described does not help either, because the attacker is one of peers and not just in the network. 

The safe choice is to use GCM mode, which is available in BouncyCastle. Probably you just have to replace CBCBlockCipher by GCMBlockCipher but I haven't read the docs.


Actually I think you assume that it is obvious the secret key cannot be given to everybody, however there is not basis for this assumption.
Okay, my point was the other way: I assume it's not obvious that it is okay to give out the secret key. Indeed, if you look at the description of NaCl, the security model section (http://nacl.cr.yp.to/box.html) and the referenced paper do not claim that the message stays secret in a situation where the senders's secret key is known, even if the recipient's secret key is not.

Still, publishing the sender's key seems to be for that NaCl scheme, and everything else would surprise me, but I haven't looked at it in detail...
legendary
Activity: 1176
Merit: 1134
@TimRuffing

in your paper you say that the change can also be shuffled, but I do not see how it can avoid being correlated due to the specific amount of the change relative to the input. What I have done is separate the outputs into the shuffled amounts and change amounts and treat the change outputs at just one step above the normal unspents.
This is a misunderstanding actually. You don't get any privacy for the change, so we don't say that the change can be shuffled. The paragraph in the paper just clarifies that you can add change addresses to the list of output of the CoinJoin transaction in case some peer does not have the exact shuffle amount (which will be almost always the case, just as for ordinary transactions). As far as I understand, this is what your implementation does?

yes, I shuffle the change treating them as ordinary outputs, but categorize it as "jumblrchange", so it is not counted as being shuffled. though i think it is marginally more private than normal outputs, so given a choice for using inputs it seems the jumblrchange would be a bit better than ordinary unspents

I think you missed that I am generating onetime keypair from the sender side. Only the receiver's pubkey is known.
    crypto_box_keypair(onetime_pubkey.bytes,onetime_privkey.bytes);
    if ( (cipher= encode_str(&cipherlen,src,len,destpubkey,onetime_privkey,onetime_pubkey)) != 0 )

Since this onetime keypair is generated for each packet, I do not see how this is linkable.
I missed that indeed. However, it is still linkable even with new keypairs: assume again that the attacker controls P2 and P50. Then P2 sees which key belongs to P1, and P50 can use that knowledge the determine P1's output address.

You say that this is fixed now by using a common account. How does that work? Did you also change the encryption scheme? The current scheme needs a the secret key even for encrypting. So I don't see how that should work, because you obviously cannot give that secret key to everybody.
Actually I think you assume that it is obvious the secret key cannot be given to everybody, however there is not basis for this assumption.

#define GENESISPRIVKEYSTR "1259ec21d31a30898d7cd1609f80d9668b4778e3d97e941044b39f0c44d2e51b"

The genesis account in NXT is a special account and its privkey is known. So I can use the genesis privkey to encrypt all messages and for decrypting, all nodes use the genesis pubkey (in addition to their privkey)

I did feel there was some sort of clever attack like your P2+Plast and so it is good to go to no leakage at all. If everybody is using the same account, it is like a public payphone, a call from that number doesnt link to any specific person (we ignore the cameras recording the payphone as it is only an analogy)

James
sr. member
Activity: 392
Merit: 250
Mixer is essentially this
1) You send bitcoins to an address(from the bitcoin mixer service)
2) After the payment is recieved in the address, the service sends you your btc to your 2nd address through a completely random address.

This is how a centralized mixer works. The way coin shuffling will work in Nxt is a bit different:

You announce that you want to shuffle for example 10,000 NXT, or join an existing shuffle that somebody else started. You enter in your wallet the recipient address, known only to you, where those 10,000 NXT should be sent. Those are deducted from your account. Each shuffle participant does the same (shuffling exactly the same amount), and each shuffle when created is set to require a certain number of participants (say 20) and the amount being shuffled. When the shuffle completes, each participant finds that amount in the recipient account he specified, yet none of the other participants, and no external observer, can find out which recipient account belongs to which participant.

Shuffling will be possible not only for the NXT coin itself, but for any asset on the NXT Asset Exchange too.

The jumblr service that James is working on is for BTC and similar coins, but the idea is the same.
sr. member
Activity: 392
Merit: 250
Actually, I don't think we use AES in authenticated mode, here is how it is called, using the BouncyCastle library:

Code:
    public static byte[] aesEncrypt(byte[] plaintext, byte[] key) {
        try {
            byte[] iv = new byte[16];
            secureRandom.get().nextBytes(iv);
            PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
                    new AESEngine()));
            CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
            aes.init(true, ivAndKey);
            byte[] output = new byte[aes.getOutputSize(plaintext.length)];
            int ciphertextLength = aes.processBytes(plaintext, 0, plaintext.length, output, 0);
            ciphertextLength += aes.doFinal(output, ciphertextLength);
            byte[] result = new byte[iv.length + ciphertextLength];
            System.arraycopy(iv, 0, result, 0, iv.length);
            System.arraycopy(output, 0, result, iv.length, ciphertextLength);
            return result;
        } catch (InvalidCipherTextException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }
where the shared key is obtained as:
Code:
    public static byte[] getSharedKey(byte[] myPrivateKey, byte[] theirPublicKey) {
        return sha256().digest(getSharedSecret(myPrivateKey, theirPublicKey));
    }
    private static byte[] getSharedSecret(byte[] myPrivateKey, byte[] theirPublicKey) {
        try {
            byte[] sharedSecret = new byte[32];
            Curve25519.curve(sharedSecret, myPrivateKey, theirPublicKey);
            return sharedSecret;
        } catch (RuntimeException e) {
            Logger.logMessage("Error getting shared secret", e);
            throw e;
        }
    }

However, after encryption, the full list of ciphertexts that each participant sends to the next becomes a part of the transaction bytes that are signed by this participant (using his regular private key, as derived from the secret phrase without additional nonces, as done for all Nxt transactions). So modifying anything inside the encrypted payload will invalidate the transaction and it will no longer be acceptable in the blockchain. And the transaction that the next participant submits, includes the hash of this previous transaction, so is only valid as a response for this specific encrypted payload.

Note that we use the same method for encrypting messages between Nxt accounts, with the difference that the shared key is derived adding a random nonce for each message, and the regular secret phrase, same for every transaction of this account, is used:
Code:
    public static byte[] getSharedKey(byte[] myPrivateKey, byte[] theirPublicKey, byte[] nonce) {
        byte[] dhSharedSecret = getSharedSecret(myPrivateKey, theirPublicKey);
        for (int i = 0; i < 32; i++) {
            dhSharedSecret[i] ^= nonce[i];
        }
        return sha256().digest(dhSharedSecret);
    }
and after the AES encryption step, same as above, the encrypted text becomes part of the transaction bytes that are signed by the sender.
legendary
Activity: 1176
Merit: 1134
What actually is the mixer means? As i haven't heard this before so i came to this thread but after reading all post i can't get any clue about what the mixer is actually. If anybody don't mind to explain me can you?
Mixer is essentially this
1) You send bitcoins to an address(from the bitcoin mixer service)
2) After the payment is recieved in the address, the service sends you your btc to your 2nd address through a completely random address.
Of course this is just the simplified version of it, most mixer noawadays provide many customizations for added privacy. As as you can probably guess, people do it to hide their tracks that people can track through their transactions.

Step 0) You make the brave decision to trust a third party won't steal your coins, isn't a honeypot, and isn't compromised by hackers/TLAs.
Do you realize with Jumblr, there is no third party that you have to trust?
You dont send coins to any address other than one that you specifiy
plz read the coinshuffle whitepaper for the details.

decentralized mixer != centralized mixer
newbie
Activity: 14
Merit: 10
For the encryption, for each sender we generate a new public/private key pair using curve25519, unique for each sender/shuffle/recipient combination, and then use this plus the recipient public key to generate a DH shared key, then use AES for the actual encryption.
Looks good. Smiley How exactly do you use AES? It must be something that provides authentication, i.e., either an authenticated mode (such as GCM) or a MAC must be added in the proper way.

Independently of James' work, we are also working on implementing coin shuffling using your algorithm in the upcoming version of Nxt. The blame phase is really the complicated part to get right, and here we are taking the approach to disclose the one-time keys used by each participant, to find and penalize the rogue participant. When ready, we would certainly welcome you to have a look at our implementation too.
Sorry, I forgot to reply to that. I offered that already to lyaffe some time ago. I'm not sure if I have the time to go through it line-by-line but I can certainly have a close look. Smiley
legendary
Activity: 2156
Merit: 1072
Crypto is the separation of Power and State.
What actually is the mixer means? As i haven't heard this before so i came to this thread but after reading all post i can't get any clue about what the mixer is actually. If anybody don't mind to explain me can you?
Mixer is essentially this
1) You send bitcoins to an address(from the bitcoin mixer service)
2) After the payment is recieved in the address, the service sends you your btc to your 2nd address through a completely random address.
Of course this is just the simplified version of it, most mixer noawadays provide many customizations for added privacy. As as you can probably guess, people do it to hide their tracks that people can track through their transactions.

Step 0) You make the brave decision to trust a third party won't steal your coins, isn't a honeypot, and isn't compromised by hackers/TLAs.
hero member
Activity: 532
Merit: 500
You have eyes but can see Mt. Tai?!
What actually is the mixer means? As i haven't heard this before so i came to this thread but after reading all post i can't get any clue about what the mixer is actually. If anybody don't mind to explain me can you?
Mixer is essentially this
1) You send bitcoins to an address(from the bitcoin mixer service)
2) After the payment is recieved in the address, the service sends you your btc to your 2nd address through a completely random address.
Of course this is just the simplified version of it, most mixer noawadays provide many customizations for added privacy. As as you can probably guess, people do it to hide their tracks that people can track through their transactions.
legendary
Activity: 1218
Merit: 1006
What actually is the mixer means? As i haven't heard this before so i came to this thread but after reading all post i can't get any clue about what the mixer is actually. If anybody don't mind to explain me can you?
sr. member
Activity: 392
Merit: 250
Thanks for the explanation, now I added a check for duplicate data at each processing step.

For the encryption, for each sender we generate a new public/private key pair using curve25519, unique for each sender/shuffle/recipient combination, and then use this plus the recipient public key to generate a DH shared key, then use AES for the actual encryption. If you take a look at the current way public keys are generated based on secret phrase: https://bitbucket.org/JeanLucPicard/nxt/src/369546f91ba32142562c18d224369ea64a3f0720/src/java/nxt/crypto/Crypto.java?at=master#Crypto.java-63 , for shuffling I have added generation of one-time keys based on secretPhrase plus known nonces:

Code:
    public static byte[] getKeySeed(String secretPhrase, byte[]... nonces) {
        MessageDigest digest = Crypto.sha256();
        digest.update(Convert.toBytes(secretPhrase));
        for (byte[] nonce : nonces) {
            digest.update(nonce);
        }
        return digest.digest();
    }

    public static byte[] getPublicKey(byte[] keySeed) {
        byte[] publicKey = new byte[32];
        Curve25519.keygen(publicKey, null, Arrays.copyOf(keySeed, keySeed.length));
        return publicKey;
    }

    public static byte[] getPublicKey(String secretPhrase) {
        byte[] publicKey = new byte[32];
        Curve25519.keygen(publicKey, null, Crypto.sha256().digest(Convert.toBytes(secretPhrase)));
        return publicKey;
    }

    public static byte[] getPrivateKey(byte[] keySeed) {
        byte[] s = Arrays.copyOf(keySeed, keySeed.length);
        Curve25519.clamp(s);
        return s;
    }

    public static byte[] getPrivateKey(String secretPhrase) {
        byte[] s = Crypto.sha256().digest(Convert.toBytes(secretPhrase));
        Curve25519.clamp(s);
        return s;
    }

and for the one-time keys used in the shuffle, shuffleId and recipientId are used as nonces. Then the one-time sender public key is added to the encrypted data, to allow its decryption by the recipient, yet it is not possible for the recipient (or anyone else) to tell who the sender of each encrypted data is.

If the blame phase needs to be entered, each participant discloses the array of sha256 digests ("keySeeds") used to generate each public/private key pair he used to encrypt to each of the next participants, which allows anyone to decrypt the content ot the data.
newbie
Activity: 14
Merit: 10
@TimRuffing

in your paper you say that the change can also be shuffled, but I do not see how it can avoid being correlated due to the specific amount of the change relative to the input. What I have done is separate the outputs into the shuffled amounts and change amounts and treat the change outputs at just one step above the normal unspents.
This is a misunderstanding actually. You don't get any privacy for the change, so we don't say that the change can be shuffled. The paragraph in the paper just clarifies that you can add change addresses to the list of output of the CoinJoin transaction in case some peer does not have the exact shuffle amount (which will be almost always the case, just as for ordinary transactions). As far as I understand, this is what your implementation does?



Each peer must check that there are no duplicate plaintexts after decrypting. Otherwise attacks on unlinkability are possible.
Is that the same as checking that no two recipient addresses are the same, once the shuffle reaches the last participant, or is there more to it?

Multiple participants submitting the same recipient account would be a trivial attack to counteract, however there is no way to protect against a real sybil attack in which multiple participants, each submitting a different recipient address, are actually controlled by the same entity.
Right, this cannot be prevented. The reason checking for checking for duplicates is indeed different and there's more to it than just checking at the end.

Consider a shuffle of 50 participants with peers P1, ..., P50 (in that order). The attacker controls the two peers P2 and P50. Without the duplicate check, the attacker can break the unlinkability of P1 entirely.

The attack is as follows:
P2 (attacker) receives a single ciphertext from P1 (technically, it's a list of ciphertexts with one entry so far) and removes one layer of encryption, resulting in another ciphertext C1. C1 has still 49 layers of encryption and the inner plaintext is the output address OUT1 of P1.

P2 is now supposed to add his own ciphertext C2 (again 49 layers of encryption, inner plaintext his output address OUT2).
However P2 just duplicates the ciphertext C1, i.e., sets C2 = C1. So P2 sends in fact [C1, C1] to P3.

Then the protocol continues normally but P1's output address OUT1 is now the only one that is there twice. Now assume that the honest participants P3, ..., P49 do not check for duplicates after decryption. The last participant P50 (attacker), who removes the innermost layer of encryption, will obtain a list of 50 output addresses. All of these addresses will be different except for P1's output address OUT1, which is the only address that appears twice in the list! So P50 just knows P1's output address, i.e., unlinkability is totally broken for P1.

To ensure that the attack remains undetected, P50 corrects the list of output addresses before publishing it, i.e., P50 replaces one of the OUT1 entries by an address under the control of the attacker. Note that P2 will not complain that his output address is not there in the final list, because P2 is controlled by attacker, too.

So the attacker can fully deanonymize P1 with only two peers in the right positions. In contrast, if the protocol is implemented correctly, the attacker needs 49 peers to fully deanonymize P1, i.e., everybody expect P1 need to be malicious.

This example where the attacker is in the second and the last position is the worst case for P1 and easy to explain, but the attack works also if the attacker is in other positions and wants to decrease the size of the anonymity set for other peers.



I think you missed that I am generating onetime keypair from the sender side. Only the receiver's pubkey is known.
    crypto_box_keypair(onetime_pubkey.bytes,onetime_privkey.bytes);
    if ( (cipher= encode_str(&cipherlen,src,len,destpubkey,onetime_privkey,onetime_pubkey)) != 0 )

Since this onetime keypair is generated for each packet, I do not see how this is linkable.
I missed that indeed. However, it is still linkable even with new keypairs: assume again that the attacker controls P2 and P50. Then P2 sees which key belongs to P1, and P50 can use that knowledge the determine P1's output address.

You say that this is fixed now by using a common account. How does that work? Did you also change the encryption scheme? The current scheme needs a the secret key even for encrypting. So I don't see how that should work, because you obviously cannot give that secret key to everybody.
legendary
Activity: 2156
Merit: 1072
Crypto is the separation of Power and State.
As amazingly good that xmr is, I think BTC -> BTC is a much easier path as it doesnt have to go through a market trading. unless you are saying that xmr is better than btc?

XMR isn't "better than" BTC for all purposes, but on-chain mixing (via ring signature+steal addresses) is infinitely superior to off-chain obfuscation.
legendary
Activity: 1176
Merit: 1134
let me get this straight. this requires use of 3 block chains? btcd, btc, and nxt? so do we have to download all 3 blockchains on our local to utilize this decentralized coinshuffling?

BTCD and NXT are very low volume, so they are worse than useless for obfuscating BTC tx.

Any significant amount of BTC volume sticks out like a sore thumb on the other two (silent abandoned ghost town) chains.

Use Monero and XMR.to if you want real (ie on-chain zero-knowledge) unlinkablity for your BTC.
There is no converting of BTC to anything. The coinshuffle creates a BTC transaction which uses the BTC blockchain, which is far more volumes than the monero blockchain

the shuffle tx never hits either the NXT or BTCD blockchain. so their volumes are irrelevant

So if you are saying that there is a problem with the coinshuffle algo, I am eager to hear how it is inferior as I am implementing the coinshuffle (without the conflict resolution for now)

As amazingly good that xmr is, I think BTC -> BTC is a much easier path as it doesnt have to go through a market trading. unless you are saying that xmr is better than btc?
legendary
Activity: 1176
Merit: 1134
let me get this straight. this requires use of 3 block chains? btcd, btc, and nxt? so do we have to download all 3 blockchains on our local to utilize this decentralized coinshuffling?
for now it is the quickest way to get it working as I built it on top of InstantDEX

But the BTCD blockchain is not needed even now for this to work for BTC. It is using the NXT address just for a directory. So it would be possible to make it just require the BTC blockchain
legendary
Activity: 817
Merit: 1000
let me get this straight. this requires use of 3 block chains? btcd, btc, and nxt? so do we have to download all 3 blockchains on our local to utilize this decentralized coinshuffling?

BTCD and NXT are very low volume, so they are worse than useless for obfuscating BTC tx.

Any significant amount of BTC volume sticks out like a sore thumb on the other two (silent abandoned ghost town) chains.

Use Monero and XMR.to if you want real (ie on-chain zero-knowledge) unlinkablity for your BTC.

Doesn't seem like you have any clue how this actually works. The volume on those two coins has absolutely no importance on the api's he is using here.



without massive spreads, costs, volatility and other risks.
legendary
Activity: 2156
Merit: 1072
Crypto is the separation of Power and State.
let me get this straight. this requires use of 3 block chains? btcd, btc, and nxt? so do we have to download all 3 blockchains on our local to utilize this decentralized coinshuffling?

BTCD and NXT are very low volume, so they are worse than useless for obfuscating BTC tx.

Any significant amount of BTC volume sticks out like a sore thumb on the other two (silent abandoned ghost town) chains.

Use Monero and XMR.to if you want real (ie on-chain zero-knowledge) unlinkablity for your BTC.
sr. member
Activity: 350
Merit: 252
let me get this straight. this requires use of 3 block chains? btcd, btc, and nxt? so do we have to download all 3 blockchains on our local to utilize this decentralized coinshuffling?
legendary
Activity: 1176
Merit: 1134
I made an improvement to the sending privacy. Instead of using a onetime keypair, I will just use a commonly known account (NXT genesis acct). that way all senders will look like the same sender and thus reveals no information

the old way of onetime keypair was good, but against an attacker that is monitoring and logging packet level data, some information would leak. not sure they can construct any meaningful statistical correlations from that, but by using the same fixed account for all senders, this is removed

In the same vein, the final step of broadcasting the sigs would be vulnerable to the attacker to allow IP correlation. it is not on the blockchain, so not as bad as it sounds, but still might as well protect this also. It will double the time to do a round as I will have to do the layered encryption, but since the code for this is already done, it wont take much more work to do.

The following is a simplified three node shuffle between A, B and C

All encryptions are done using the same sender, the genesis account, which has a known privkey and pubkey.

A encrypts his vin and vout and change from genesis to C, then encrypts the output of that from genesis to B and sends this to B. The sending to B is done via a global broadcast of an encrypted packet, so all nodes will receive it. Again the encryption of this packet is done as the genesis account sending to B.

The network layer decrypts the packet and if it is not garbage, it calls the jumblr incoming packet processing. Only node B will be able to decrypt this and it will look like it came from the genesis account, but B will know the NXT address that sent the packet as this was agreed to from the orderbook. However, this NXT address is just an abstract address not connected to anything else.

B now peels off the layer of encryption for the vin, vout and change. He also creates his own set of vin, vout, change and encrypts it as the genesis account to C. Then he scrambles the vins, vouts (change is treated as normal vout) and the shuffled set of encrypted vins, vouts are broadcast to the network, pretending to be the genesis account.

All nodes receive the packet, but only C can decrypt it and he also decrypts all the vins and vouts and is able to construct a raw transactions without any signatures. He then broadcasts this without encrypting. Since it is known C is participating in the shuffle, I dont think an non-encrypted broadcast of the unsigned rawtx is leaking any important information.

All nodes receive the packet, the ones participating in this shuffle, then validate the raw transaction to make sure their vin, vout and change are there and also that there are no duplicates. If all is good, they create a signature for their vin and broadcast it. (this is the weakest link right now as the first node in the broadcast packet will know their vin, but not their vout)

All the participating nodes assembled a signed transaction out of the incoming sigs and when all signatures have arrived, they check their mempool to see if the transaction has already arrived from another participant. If not, they sendrawtransaction.

I hope the above clarifies my implementation. Any flaws found will be fixed and the leakage of IP address to vin in the sig broadcast seems to be the biggest leak, so I will fix that next

James
legendary
Activity: 1176
Merit: 1134
@TimRuffing

in your paper you say that the change can also be shuffled, but I do not see how it can avoid being correlated due to the specific amount of the change relative to the input. What I have done is separate the outputs into the shuffled amounts and change amounts and treat the change outputs at just one step above the normal unspents.

I also think that to be using specific shuffled change outputs in future shuffles will contaminate things, so while it is a bit better than the transparent unspents, it is nowhere near as private as the shuffled amounts (assuming all the shuffled outputs in a round are the same value)

By allowing shuffle rounds to happen every minute, it will be possible to reshuffle already shuffled outputs and the wallet can track how many shuffles (and participants) each unspent has gone through to create a privacy metric.

James
legendary
Activity: 1176
Merit: 1134
I just verified a 5 node shuffle. start to finish was about 12 seconds

http://explorebtcd.info/tx/8cfcfba6ef25443c5e9b9c0de5706f0809e9bd559dfbe072ef31d1239b2af41e

The most time is due to the serial nature of getting the full transaction to the final node. However, once the unsigned rawtx is broadcast, all nodes calculate their sigs and broadcast them, so the phase of collecting the sigs and constructing the fully signed tx will take about the same time, regardless of 3 or 13 nodes.

All these comms are happening offchain without any financial cost, so even if it is disrupted, then it is not a big loss. Of course, if somebody is actively sabotaging things, there would need to be a layer to blacklist the bad actors. But that sort of thing i will save for another weekend. Once there are significantly more than 13 nodes available to shuffle with, then it will be possible to generate historical statistics on the effect a specific node has on the success rate. Granted it isnt as elegant as the conflict resolution with fancy math, but with extra rounds it would be possible to statistically identify the bad actors. newbie accts would then be added to the shuffle group at the lowest priority.

For now, it would be nice to get some people testing this a bit more.

James
sr. member
Activity: 392
Merit: 250
Each peer must check that there are no duplicate plaintexts after decrypting. Otherwise attacks on unlinkability are possible.
Is that the same as checking that no two recipient addresses are the same, once the shuffle reaches the last participant, or is there more to it?

Multiple participants submitting the same recipient account would be a trivial attack to counteract, however there is no way to protect against a real sybil attack in which multiple participants, each submitting a different recipient address, are actually controlled by the same entity.

Independently of James' work, we are also working on implementing coin shuffling using your algorithm in the upcoming version of Nxt. The blame phase is really the complicated part to get right, and here we are taking the approach to disclose the one-time keys used by each participant, to find and penalize the rogue participant. When ready, we would certainly welcome you to have a look at our implementation too.
legendary
Activity: 1176
Merit: 1134
turned out it wasnt a bug, just make sure when testing that you dont use a copy of the same wallet on two nodes!

I hope that others can test as I can only test with 5 nodes and it is better to be doing 13 nodes at once and I want to make sure that works

If anybody can work as a tester, I will be able to pay for time.

James
legendary
Activity: 1176
Merit: 1134
its a good thing I added duplicate checking!
found a bug with 4 participants with a duplicated input. considering I started coding this last Friday, I am pleased at how fast it has come together. 3-way shuffles seem to work for both BTC and BTCD and should work for any bitcoin fork as I only use standard pay to pubkeyhash

./BitcoinDarkd SuperNET '{"plugin":"InstantDEX","method":"placebid","base":"BTCD","exchange":"jumblr","volume":0.01}'

using the github.com/jl777/btcd , the above will add an entry to the InstantDEX orderbook for "BTCD" in the meta-exchange "jumblr"
this propagates to all the SuperNET nodes with InstantDEX active.

./BitcoinDarkd SuperNET '{"plugin":"InstantDEX","method":"orderbook","base":"BTCD","exchange":"jumblr","allfields":1}'
the above is a way to see how many different nodes are ready to shuffle

./BitcoinDarkd SuperNET '{"plugin":"jumblr","method":"start","dotrade":1,"volume":0.01,"base":"BTCD","timeout":20000}'
the above starts a shuffle round.

For now, only up to 3 has been verified and 4 had a bug. by changing "base" to "BTC" or any other coin, it will shuffle that coin. For coins I dont have the address type and script type for, just get me that info and I will add it to the list of supported coins

James
legendary
Activity: 1176
Merit: 1134
pushed a fix so that if any vout or vin is duplicated, it is rejected

Let me know if there are any other issues.

I use a broadcast protocol for all the comms, so correlating IP addresses will require packet level analysis, but even this will be close to noise level once there is significant network activity as the response time for all broadcast packets is randomized via the anti-Ddos mechanism built into SuperNET

What is known about the participants are their NXT addresses, but these are likely to be a onetime or temporary address. Using this, we get the curve25519 pubkey to do the encryption with. Only the destination's pubkey is known, the sender uses a randomly generated onetime (per packet) keypair. So no way to link the data to the published address.

The destination addresses are also fresh never before used addresses.

I am seeing a small round of 3 nodes complete in ~5 seconds. With 13 participants, I hope to achieve ~30 seconds per shuffle. So if one is messed up, it is no disaster.

James
legendary
Activity: 1176
Merit: 1134
I'm one of the authors of the CoinShuffle paper. Really fantastic to see that people are interested in the protocol!

I had a brief look at the code and I think there are several severe problems:
  • You use authenticated public-key encryption (from the NaCl library). It has the property that a recipient can be sure who created a given ciphertext. This is exactly the opposite of what we need in CoinShuffle. In fact, the whole point of shuffling is to hide that information from the recipient.
    We need normal IND-CCA encryption, e.g., or DHIES.
    So your implementation does not provide anonymity (or unlinkability as dubbed in the paper).
  • Each peer must check that there are no duplicate plaintexts after decrypting. Otherwise attacks on unlinkability are possible.
  • The whole blame phase is missing, so there is no robustness against DoS attacks as described in the paper. This is actually not a huge problem for a first implementation for a first implementation but should be noted because you implemented currently only a subset of the full CoinShuffle protocol.
(The list is not necessarily complete; these are just the problems that I've seen immediately.)

The problem is that the paper as-is is written for crypto researchers and is quite high-level. I think the protocol is not overly complex but the devil is in the details as with all crypto.

I've just started a collaboration with Kristov Atlas. We will write a BIP draft including a more detailed, development-oriented specification of the protocol including all the nitty-gritty details. We also plan talk to wallet developers and I will definitively write some code as soon as a reasonable version of the BIP is there. Contributions and collaborations are welcome in all stages, of course. Smiley

There are also some open questions, e.g., how to find participants for the shuffling, and what to use for communication (on a network level). How is that done in your implementation?

I think you missed that I am generating onetime keypair from the sender side. Only the receiver's pubkey is known.
    crypto_box_keypair(onetime_pubkey.bytes,onetime_privkey.bytes);
    if ( (cipher= encode_str(&cipherlen,src,len,destpubkey,onetime_privkey,onetime_pubkey)) != 0 )

Since this onetime keypair is generated for each packet, I do not see how this is linkable.

As far as conflict resolution, I use the ethernet method, ie. if something goes wrong, try again with a different set of participants. Since I am using a realtime network to do the comms, a full round will finish in less than a minute. i use InstantDEX orderbook to establish the list of participants.

James

P.S. I will add check for no duplicates
newbie
Activity: 14
Merit: 10
I'm one of the authors of the CoinShuffle paper. Really fantastic to see that people are interested in the protocol!

I had a brief look at the code and I think there are several severe problems:
  • You use authenticated public-key encryption (from the NaCl library). It has the property that a recipient can be sure who created a given ciphertext. This is exactly the opposite of what we need in CoinShuffle. In fact, the whole point of shuffling is to hide that information from the recipient.
    We need normal IND-CCA encryption, e.g., or DHIES.
    So your implementation does not provide anonymity (or unlinkability as dubbed in the paper).
  • Each peer must check that there are no duplicate plaintexts after decrypting. Otherwise attacks on unlinkability are possible.
  • The whole blame phase is missing, so there is no robustness against DoS attacks as described in the paper. This is actually not a huge problem for a first implementation for a first implementation but should be noted because you implemented currently only a subset of the full CoinShuffle protocol.
(The list is not necessarily complete; these are just the problems that I've seen immediately.)

The problem is that the paper as-is is written for crypto researchers and is quite high-level. I think the protocol is not overly complex but the devil is in the details as with all crypto.

I've just started a collaboration with Kristov Atlas. We will write a BIP draft including a more detailed, development-oriented specification of the protocol including all the nitty-gritty details. We also plan talk to wallet developers and I will definitively write some code as soon as a reasonable version of the BIP is there. Contributions and collaborations are welcome in all stages, of course. Smiley

There are also some open questions, e.g., how to find participants for the shuffling, and what to use for communication (on a network level). How is that done in your implementation?
legendary
Activity: 1176
Merit: 1134
...

jl777

Please post some more details of your project.  There are many of us interested in the topic of how to better to hide BTC transactions (to improve financial privacy).

I am not expert by any means.  But, I have found both bitmixer.io and SharedCoin (blockchain.info's mixing service) to be pretty good services, both charge under 1%.  And, importantly, are not scams.


[Unfortunately, I do not code, I cannot read C.  But, that is why we are a community here.  Good luck, keep us posted.]
https://blockchain.info/search?search=18144ad2e7c4f6ab8cd5b85fb794d943099085d50e4fcc1de6de3d11fc597531

the above is the first jumblr shuffle

when the shuffle starts, all participants create a brand new keypair
they also know all the participants NXT addresses
let us say A, B and C are shuffling
A would then encrypt his data using layered encryption
so vin and vout in 2 separate blobs of data
first it is encrypted to C, then that data is encrypted to B
this is sent to B, who peels off one layer
notice that now what B got from A is encrypted to C, but B cant see what the data is
B encrypts his data to C and then shuffles his data and the received data and sends it to C
C now receives and decrypts it and has the real data, but other than his own data he doesnt know if it was from A or B
now he broadcasts the full transaction to everyone
everybody verifies his data wasnt changed and signs it and broadcasts the signature
everybody constructs the full transaction from all the incoming signatures and they all submit to the network

The above process is fully automated, so you just need to issue an API call to allow the coinshuffle. there is also an API call that lets you initiate a shuffle round.

James
legendary
Activity: 2940
Merit: 1865
...

jl777

Please post some more details of your project.  There are many of us interested in the topic of how to better to hide BTC transactions (to improve financial privacy).

I am not expert by any means.  But, I have found both bitmixer.io and SharedCoin (blockchain.info's mixing service) to be pretty good services, both charge under 1%.  And, importantly, are not scams.


[Unfortunately, I do not code, I cannot read C.  But, that is why we are a community here.  Good luck, keep us posted.]
legendary
Activity: 1176
Merit: 1134
I am not sure if this is the right place to post about this, but this weekend I wrote a SuperNET agent which implements the coinshuffle (http://crypsys.mmci.uni-saarland.de/projects/CoinShuffle/coinshuffle.pdf) using realtime offchain broadcast packets.

Once there are enough participants, the privacy achieved will be close to using bitmessage for mixing, eg very, very good.

You need to have a bitcoin RPC available locally and at no time do you lose control of your funds. I searched, but I could not find any other decentralized bitcoin mixer, so maybe mine is the first?

Since there are no servers to manage, the costs are low, but it does use the network and so I set the fee at 0.1%. This allows many rounds of shuffling for the same cost as the centralized mixers without any third party risk.

This all came together so fast (https://github.com/jl777/btcd/blob/master/libjl777/plugins/agents/shuffle777.c) it doesnt even have a name yet!

I am looking for people to help test this and also to market this service. It is implemented as a meta-exchange called "shuffle" within InstantDEX, but it really is a totally different type of function and it works with bitcoins or any bitcoin fork without any changes needed.

To go from the low level API to a usable service, I think the following things are needed:

1. Name
2. GUI
3. Testing
4. Marketing

I hope to find people that can help as the only thing I can do well is write C code.

James



Jump to: