Skip to content

Commit 2670a82

Browse files
committed
Optimize addmod() for elliptic curve context
In elliptic curve context the x and y arguments are already reduced modulo mod. Here we can pick up similar condition and provide optimized implementation for such case. This case is 2x faster with little overhead for other cases. Based on holiman/uint256#86.
1 parent e05e571 commit 2670a82

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

include/intx/intx.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,24 @@ inline constexpr uint<N>& operator>>=(uint<N>& x, const T& y) noexcept
19431943

19441944
inline uint256 addmod(const uint256& x, const uint256& y, const uint256& mod) noexcept
19451945
{
1946+
// Fast path for mod >= 2^192, with x and y at most slightly bigger than mod.
1947+
// This is always the case when x and y are already reduced modulo mod.
1948+
// Based on https://github.com/holiman/uint256/pull/86.
1949+
if ((mod[3] != 0) && (x[3] <= mod[3]) && (y[3] <= mod[3]))
1950+
{
1951+
auto s = sub_with_carry(x, mod);
1952+
if (s.carry)
1953+
s.value = x;
1954+
1955+
auto t = sub_with_carry(y, mod);
1956+
if (t.carry)
1957+
t.value = y;
1958+
1959+
s = add_with_carry(s.value, t.value);
1960+
t = sub_with_carry(s.value, mod);
1961+
return (s.carry || !t.carry) ? t.value : s.value;
1962+
}
1963+
19461964
const auto s = add_with_carry(x, y);
19471965
uint<256 + 64> n = s.value;
19481966
n[4] = s.carry;

0 commit comments

Comments
 (0)