Skip to content

Commit

Permalink
Avoid curve25519 "left shift of negative value"
Browse files Browse the repository at this point in the history
Cast to unsigned before performing the left shift. The shifted result is
then sign extended back before subtraction, giving the same output.
Generated assembly is unaltered with this change, checking gcc 14.2.0
and clang 19.1.1 (x86-64).

The same unsigned cast fix is present in crypto++'s tweetnacl version.
weidai11/cryptopp@5be0c0a#diff-067e6f20b212f32eb7fcdec3395fb1d145612f5d44736d041c1dfc9bc44a9d5b
Jeffery Walton's modification to modL() is also applied here.

Running with -fsanitize=undefined could report a left shift of a negative
value from car25519
        o[i]-=c<<16;

This is valid for gcc (and presumably clang), but the sanitizer report
is a problem.
https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Integers-implementation.html

Fixes #312 on github
  • Loading branch information
mkj committed Dec 4, 2024
1 parent 6652b47 commit ae19826
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ sv car25519(gf o)
o[i]+=(1LL<<16);
c=o[i]>>16;
o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
o[i]-=c<<16;
o[i]-=((u64)c)<<16;
}
}

Expand Down Expand Up @@ -363,7 +363,7 @@ sv modL(u8 *r,i64 x[64])
for (j = i - 32;j < i - 12;++j) {
x[j] += carry - 16 * x[i] * L[j - (i - 32)];
carry = (x[j] + 128) >> 8;
x[j] -= carry << 8;
x[j] -= ((u64)carry) << 8;
}
x[j] += carry;
x[i] = 0;
Expand Down

0 comments on commit ae19826

Please sign in to comment.