The Zcoin project announced yesterday that a typo in the Zerocoin source code allowed an attacker to steal 370,000 Zerocoin, which is about $592,000 at today's price. Zerocoin, also known as Zcoin or XZC, is a cryptocurrency protocol built on top of Bitcoin that implements Zero-Knowledge proofs to guarantee complete financial privacy and anonymity. Zerocoin is the precursor of Zcash and Monero, two similar cryptocurrencies that provide extra anonymity for their users, much more than the standard Bitcoin currency can provide.
According to the Zcoin team, one extra character left inside Zerocoin's source code caused a bug that an unknown attacker discovered and used to his advantage in the last few weeks. "The bug from the typo error allowed the attacker to reuse his existing valid proofs to generate additional Zerocoin spend transactions," the Zcoin team said yesterday. This allowed the crook to initiate one transaction but receive the money multiple times over.
According to the Zcoin team, the attacker (or attackers) was very sophisticated and took great care to hide his tracks. They say the attacker created numerous accounts at Zerocoin exchanges and spread transactions across several weeks so that traders wouldn't notice the uneven transactions volume. Nonetheless, as transactions piled up, the Zcoin team saw that the two sides of their blockchain weren't adding up.
The Zcoin team says they worked with various exchanges to attempt and identify the attacker but to no avail. Out of the 370,000 Zerocoin he stole, the attacker has already sold 350,000. The Zcoin team estimates the attacker made a net profit of 410 Bitcoin ($437,000).
Source:
(Score: 5, Informative) by Lagg on Monday February 20 2017, @09:25PM
From my research. It looks to be like a fix that is slightly larger and slightly dirtier in terms of magic number hax than "1 character" if I am correct in this commit range being the fix. Can we please start putting sauce links up you guys? It's something we can do here right?
I imagine it was stated this way because frankly - and from research done by myself, a random systems programmer and not cryptography expert - the zerocoin code is bad. It's duplicated everywhere. Fix is ugly. Needs refactoring before production use. Comments in the repo itself seem to agree with this opinion.
https://github.com/zcoinofficial/zcoin/compare/33796c839f7d4df4fb89c2775ec971982cfc8996%5E...ca0bb3cabe300c204749731e3a7c3e7fa1f24c71 [github.com]
There was also a breaking commit due to what I assumed was a panicked ctrl-v. But don't judge them harshly for that. We know how it feels when prod has issues.
http://lagg.me [lagg.me] 🗿
(Score: 2, Informative) by Anonymous Coward on Monday February 20 2017, @09:36PM
I was just this commit, that fixed the issue.
https://github.com/zcoinofficial/zcoin/commit/b20c177032de3c4bfae62b5ada768a5dc2b4fa67 [github.com]
You're looking at the dev's entire pre-commit work history.
(Score: 3, Informative) by arslan on Monday February 20 2017, @10:42PM
The comment below the pull request is pretty telling... "This doesn't prevent a miner not using the reference code from including zerocoin spends in their blocks, right? Where's the change in the validation code (if you're prepared to say publicly)?"
Anyone with more deep blockchain knowledge want to chime in? Does the network somehow validates signature of running code?
(Score: 2) by inertnet on Tuesday February 21 2017, @01:33AM
Just a wild guess, but could this have been an intentional 'typo', in order to create the circumstances to pull this stunt off?
(Score: 2, Insightful) by tftp on Tuesday February 21 2017, @06:15AM
I see plenty of duplicated code, which is indicative of low quality of the software. Why don't they have a method like this?
public static Bool IsThisAValidPubCoinId(unsigned int id) { ... }
(Score: 0) by Anonymous Coward on Tuesday February 21 2017, @05:54PM
I see plenty of duplicated code, which is indicative of low quality of the software. Why don't they have a method like this?
public static Bool IsThisAValidPubCoinId(unsigned int id) { ... }
Because code wants to be free not chained to a function! :D