Live data from Hacker News

Zcoin implementation bug enabled attacker to create over 500K Zcoins

makebitcoingreatagain.wordpress.com

71–80 of 223 posts

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#71
The point I'm about to make in this comment is so old and has been said so many times that we all are tired of hearing it. But why do we use a language like C++ to implement something where we don't wish to have bugs?

C++ is not memory-safe (no GC or whatever Rust does), it's not type safe (in the ML sense), it relies on writing to memory a lot (instead of having pure functions). Had this program been written in Ocaml or Haskell or a strongly typed functional Lisp, this bug would have been impossible to make.

Why do we do this, still? Is it not irresponsible?

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#72
post #67

Earlier quoted context omitted.

You're absolutely right (to my surprise), it gives: test.cpp: In function ‘int main()’: test.cpp:13:11: warning: statement has no effect [-Wunused-value] a == b; ^ But only after enabling a warning that is not on by default. -Wall and -Werror should be the default.

-Wall sure (also, it should really enable all warnings, just as the name implies. Currently it doesn't) -Werror, I'm not sure. During development and on CI systems it makes sense. But if you intend to ship source code, it's probably best left off. Other people might be using different compilers that emit warnings for things yours didn't. You don't want the build to fail for those people.

> Other people might be using different compilers that emit warnings for things yours didn't. You don't want the build to fail for those people.

Actually, you do. That way those things will be fixed and hopefully your inclusion of their fixes is a well motivated PR away.

Switching -Werror off should be a decision made with great care and understanding of what's going on under the hood. If there are platform specific issues then people on those platforms will be the ones in the best position to determine if such a warning is actually an error or not.

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#73

The error is here: https://github.com/zcoinofficial/zcoin/blob/81a667867b5d8489... and the line of code: zccoinSpend.denomination == libzerocoin::ZQ_LOVELACE; In other words, a statement with no effect. In D, such a line gives an error, not a warning: Error: == has no effect in expression You can force the statement to be accepted by casting it to void. It's really past time for languages to not accept such code any…

gcc doesn't accept that if you enable some warnings and -Werror. I agree that the default is bad, though.

The language still accepts it, though.

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#74
post #2

> If the attacker managed to liquidate their Zcoins at an average price of $1.25, they may have netted themselves upto USD 750,000. If you are a skilled programmer / security expert / mathematician, crypto currency exploit creation seems to be an extremely lucrative hobby.

Well, crypto/bitcoin businesses in general tend to be quite lucrative. However lots of risks as well. For a security researcher there are no downside risks as much.

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#75

From the blog post explaining the bug, https://zcoin.io/language/en/zcoins-zerocoin-bug-explained-i... , how is that not a "useless statement has no side effect" warning?

It does. It seems like the devs are of the "it compiles, ship it" sort. Building the source, I'm seeing all kinds of warnings -- the code trying to return consts, warnings about sign differences, etc. Looks like lots of potential places for naughtiness to occur.

Indeed. I was hoping that the blog post would conclude with a section describing how they had learned an important lesson and would now be much more strict about dealing with this compiler warning in particular, and indeed compiler warnings in general, but there was nothing like that. Which implies it will quite likely happen again.

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#76
post #71

The point I'm about to make in this comment is so old and has been said so many times that we all are tired of hearing it. But why do we use a language like C++ to implement something where we don't wish to have bugs? C++ is not memory-safe (no GC or whatever Rust does), it's not type safe (in the ML sense), it relies on writing to memory a lot (instead of having pure functions). Had this program been written in Ocam…

Luckily there are some Blockchain/Crypto currency startups that do understand the value of using something like Haskell. See https://iohk.io/projects/cardano/

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#77
post #45

I always wonder how these "five conditions ANDed together in an if" make it past code review in general (i know thats not where the actual bug was). I don't care how brilliant a programmer you are, but mistakes in those are very difficult to grasp.

That's the equivalent of a 32 branch switch statement in one line. So only 31 other cases to test for, now let's hope they did all those tests.

I'm definitely not advocating for unnecessarily complex or long conditionals on a single line or any other hard-to-grok code, but this comment reminded me of something I just learned recently! Someone on my team introduced me to property-based testing, which generates ranges of test cases that would otherwise be very repetitive to write manually. We've used http://hypothesis.works/ in a few places recently and caught bugs that we might have missed if we had just written tests the usual way.

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#78

The error is here: https://github.com/zcoinofficial/zcoin/blob/81a667867b5d8489... and the line of code: zccoinSpend.denomination == libzerocoin::ZQ_LOVELACE; In other words, a statement with no effect. In D, such a line gives an error, not a warning: Error: == has no effect in expression You can force the statement to be accepted by casting it to void. It's really past time for languages to not accept such code any…

You're absolutely right (to my surprise), it gives: test.cpp: In function ‘int main()’: test.cpp:13:11: warning: statement has no effect [-Wunused-value] a == b; ^ But only after enabling a warning that is not on by default. -Wall and -Werror should be the default.

> But only after enabling a warning that is not on by default. -Wall and -Werror should be the default.

This, a hundred times. Building without proper warnings (and without proper tests, review) is just bad engineering, and mediocre coding.

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#79
post #71

The point I'm about to make in this comment is so old and has been said so many times that we all are tired of hearing it. But why do we use a language like C++ to implement something where we don't wish to have bugs? C++ is not memory-safe (no GC or whatever Rust does), it's not type safe (in the ML sense), it relies on writing to memory a lot (instead of having pure functions). Had this program been written in Ocam…

Because old habits die hard.

Using 'unmanaged' languages for 'performance' reasons is no longer a good reason, because the likes of C# have shown multiple times that there is no reason to choose C++ over C# if you look at performance alone (difference is neglible).

Re: Zcoin implementation bug enabled attacker to create over 500K Zcoins

#80
post #79
post #71

The point I'm about to make in this comment is so old and has been said so many times that we all are tired of hearing it. But why do we use a language like C++ to implement something where we don't wish to have bugs? C++ is not memory-safe (no GC or whatever Rust does), it's not type safe (in the ML sense), it relies on writing to memory a lot (instead of having pure functions). Had this program been written in Ocam…

Because old habits die hard. Using 'unmanaged' languages for 'performance' reasons is no longer a good reason, because the likes of C# have shown multiple times that there is no reason to choose C++ over C# if you look at performance alone (difference is neglible).

The difference is not negligible:

http://benchmarksgame.alioth.debian.org/u64q/compare.php?lan...

Sure, it's silly benchmarks, so I wouldn't take the results as gospel. But the fact is, nobody who writes C# managed to produce a benchmark yet that beats a C++ program.

Fast languages like Rust have managed to at least match the performance of C in some benchmarks (and even beat it in others).

Post reply on HN