Live data from Hacker News

Zcoin implementation bug enabled attacker to create over 500K Zcoins

makebitcoingreatagain.wordpress.com

101–110 of 223 posts

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

#101
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…

This bug had nothing to do with c++ and its ergonomics, let alone it's safety.

> Unfortunately when populating the denomination member variable, an equality operator was used instead of assignment, resulting in the denomination always being zero, as set in the class constructor.

So = Vs ==

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

#102
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…

This bug had nothing to do with c++ and its ergonomics, let alone it's safety. > Unfortunately when populating the denomination member variable, an equality operator was used instead of assignment, resulting in the denomination always being zero, as set in the class constructor. So = Vs ==

That is absolutely a bug in C++'s ergonomics. Languages that use pascal-style := for assignment would not have this problem. Languages that don't have the surprising value behaviour of = would not have this problem. Hell, even as crude a language as Java would not have this problem because it doesn't allow an integer to implicitly decay to a boolean.

Building with warnings on would also have caught it, but the fact that someone started a new project without this warning turned on shows that C++'s defaults around warnings are bad, which is an ecosystem ergonomics issue.

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

#103
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…

"We" don't. But yeah, using C++ is stupid, and anyone paying attention knows this by now. At this point the only thing is to point and laugh and raise the new generation better - I fear that, like science, programming practice will have to advance one funeral at a time.

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

#104

Earlier quoted context omitted.

Don't "mine" gold, sell shovles.

Don't "sell shovles", license spellcheck software.

I'd take that as not even needing to sell what's needed, sell approximately what's needed. Your snake oil just needs to make their cough hurt a bit less, not cure their tuberculosis.

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

#105
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…

It's a good point, but there's also market forces to contend with.

If you make your new coin based on a functional language, there's fewer people who'll be able to jump in and code.

c++ looks similar enough to the other {} languages that many people will have the skills to give it a go.

Unfortunately it's different enough that you can really mess things up, but you already know that.

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

#106
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…

It's a good point, but there's also market forces to contend with. If you make your new coin based on a functional language, there's fewer people who'll be able to jump in and code. c++ looks similar enough to the other {} languages that many people will have the skills to give it a go. Unfortunately it's different enough that you can really mess things up, but you already know that.

I really hope amateurs with "a {} is a {} is a {} is a {}" level skills aren't working on cryptographic or financial software in C or C++. Write Rust, though, which is {}, and at least the box of hand grenades you're giving them doesn't have all the pins pre-pulled.

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

#107
post #67

Earlier quoted context omitted.

-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…

I want to agree with you but in practice I can't really imagine switching -Werror outside of dev builds. The problem is that different compilers have different warnings and if your code is meant to be portable it's going to be a serious pain to avoid all the warnings all the time.

Having compilation break for a user because of a spurious warning due to a different compiler (or different compiler version) would make it a lot more painful to maintain.

For instance I started maintaining an old C++ codebase that generates a bunch of warnings when build with a modern g++, code like this:

    #define M "toto"

    const char *s = "tata"M;
Generates warnings like:

warning: invalid suffix on literal; C++11 requires a space between literal and string macro [-Wliteral-suffix]

Is it helpful? Sure. It is worth breaking the build for anybody using a modern g++ until I manage to fix all occurrences and release a new version? I don't think so.

An other example is building code with -Wextra which warns you when some comparisons become "nops". For instance:

    int toto(int i) {

      if (i 
On most modern machines this will build without a hitch, but if you compile on a 16bit machine you'll get a warning saying:

warning: comparison is always true due to limited range of data type

In my experience this particular warning is generally not a problem. On the other hand the following code:

    int i = 0xabcdef;
Will generate the following warning on 16bit architectures:

warning: integer constant is too large for its type

And that's potentially a lot nastier and should be an error IMO.

So I'd say the main problem is that C and C++ are way too permissive by default, things like comparison with no side effects ought to be errors, not warnings. And there are a bunch of others, for instance why on earth are these not errors :

    warning: no return statement in function returning non-void
    warning: ‘i’ is used uninitialized in this function
So -Werror is just killing a fly with a bazooka IMO.

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

#108

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…

The commit that fixes it does not change any tests: https://github.com/zcoinofficial/zcoin/commit/0359bcb2ead7fe... This indicates that the code in question is not covered by tests. I work on a database, for which correctness is paramount, so it's unnerving to see any code fixes not associated with test additions or changes. I would have thought that cryptocurrency had similar standards.

I think that won't even compile due to an accidentally pasted URL here: https://github.com/zcoinofficial/zcoin/commit/0359bcb2ead7fe...

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

#110
post #94

Earlier quoted context omitted.

Sorry if this is stating the obvious. I'm guessing that this was meant to be a single equals sign for an assignment rather than a double equals for an equality test?

Yep. That's all there is to it.

Great thanks
Post reply on HN