aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/news.rst4
-rw-r--r--src/lib/utils/donna128.h18
2 files changed, 16 insertions, 6 deletions
diff --git a/doc/news.rst b/doc/news.rst
index 8c4db8b09..a5f6cba72 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -12,6 +12,10 @@ Version 1.11.31, Not Yet Released
* Add KDF1 from ISO 18033 (GH #483)
+* Fix undefined behavior in Curve25519 on platforms without a native 128-bit
+ integer type. This was known to produce incorrect results on 32-bit ARM
+ under Clang. GH #532
+
* Fixes for FreeBSD (GH #517) and OpenBSD (GH #523)
* Support for getting entropy from EGD is deprecated, and will be removed in
diff --git a/src/lib/utils/donna128.h b/src/lib/utils/donna128.h
index c2a3e0d2e..2a2d1e339 100644
--- a/src/lib/utils/donna128.h
+++ b/src/lib/utils/donna128.h
@@ -23,18 +23,24 @@ class donna128
friend donna128 operator>>(const donna128& x, size_t shift)
{
donna128 z = x;
- const u64bit carry = z.h << (64 - shift);
- z.h = (z.h >> shift);
- z.l = (z.l >> shift) | carry;
+ if(shift > 0)
+ {
+ const u64bit carry = z.h << (64 - shift);
+ z.h = (z.h >> shift);
+ z.l = (z.l >> shift) | carry;
+ }
return z;
}
friend donna128 operator<<(const donna128& x, size_t shift)
{
donna128 z = x;
- const u64bit carry = z.l >> (64 - shift);
- z.l = (z.l << shift);
- z.h = (z.h << shift) | carry;
+ if(shift > 0)
+ {
+ const u64bit carry = z.l >> (64 - shift);
+ z.l = (z.l << shift);
+ z.h = (z.h << shift) | carry;
+ }
return z;
}