Crypto Review Completed, please read. Thanks to Jesse James for completing with thorough review and BloodyRookie for reference.
From Jesse James:"I spent some quality time reviewing the core crypto NXT relies on. As part of my review I re-implemented the relevant algorithms
https://gist.github.com/doctorevil/9521126 using a different approach in a different language to make sure I understood everything deeply. Although the implementation NXT uses doesn't follow certain algorithm specifications to the letter, the deviations noted (motivated by simplicity and/or performance) seemed reasonable and in general nothing stuck out as a red flag. There was one bug in the signature generation function (that NXT is aware of and currently working around) for which I've provided a patch (or more precisely tweaked BloodyRookie's proposed patch). It should be should be safe for devs to incorporate this patch at their convenience.
Review:
https://gist.github.com/doctorevil/9521116Code:
https://gist.github.com/doctorevil/9521126 "
Wow.
I trust this guy more than C++ converted to Java implementation that we are using right now.
I talked to both the original C++ author and Java converter and both seem to be clueless, really.
Can we at least fix signing now?
public static final boolean sign(byte[] v, byte[] h, byte[] x, byte[] s) {
/ v = (x - h) s mod q
int w, i;
byte[] h1 = new byte[32], x1 = new byte[32];
byte[] tmp1 = new byte[64];
byte[] tmp2 = new byte[64];
/ Don't clobber the arguments, be nice!
cpy32(h1, h);
cpy32(x1, x);
/ Reduce modulo group order
byte[] tmp3=new byte[32];
divmod(tmp3, h1, 32, ORDER, 32);
divmod(tmp3, x1, 32, ORDER, 32);
/ v = x1 - h1
/ If v is negative, add the group order to it to become positive.
/ If v was already positive we don't have to worry about overflow
/ when adding the order because v < ORDER and 2*ORDER < 2^256
mula_small(v, x1, 0, h1, 32, -1);
mula_small(v, v , 0, ORDER, 32, 1);
/ tmp1 = (x-h)*s mod q
mula32(tmp1, v, s, 32, 1);
divmod(tmp2, tmp1, 64, ORDER, 32);
for (w = 0, i = 0; i < 32; i++)
w |= v = tmp1;
return w != 0;
}
This would also apply to javascript version that wesleh would use.