aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/math
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-12-03 07:10:09 -0500
committerJack Lloyd <[email protected]>2018-12-03 07:10:09 -0500
commit51cf88a8d91b8067d0b077e50d39452dd71e8b77 (patch)
tree4531225f220d07548f34fd993d0e652772384daf /src/lib/math
parentd506b715c51cf3c609d5f61d47f025c050462c92 (diff)
Extend ct_modulo to handle negative inputs
Unfortunately Barrett reductions API allows negative inputs
Diffstat (limited to 'src/lib/math')
-rw-r--r--src/lib/math/bigint/divide.cpp25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/lib/math/bigint/divide.cpp b/src/lib/math/bigint/divide.cpp
index 5e2dd92d9..2dfb7405e 100644
--- a/src/lib/math/bigint/divide.cpp
+++ b/src/lib/math/bigint/divide.cpp
@@ -20,13 +20,14 @@ namespace {
*/
void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r)
{
- if(x.sign() == BigInt::Negative)
- {
+ if(x.sign() != y.sign())
q.flip_sign();
- if(r.is_nonzero()) { --q; r = y.abs() - r; }
+
+ if(x.is_negative() && r.is_nonzero())
+ {
+ q -= 1;
+ r = y.abs() - r;
}
- if(y.sign() == BigInt::Negative)
- q.flip_sign();
}
inline bool division_check(word q, word y2, word y1,
@@ -101,7 +102,7 @@ void ct_divide_u8(const BigInt& x, uint8_t y, BigInt& q_out, uint8_t& r_out)
r = r_gte_y.select(r - y, r);
}
- if(x.sign() == BigInt::Negative)
+ if(x.is_negative())
{
q.flip_sign();
if(r != 0)
@@ -117,8 +118,8 @@ void ct_divide_u8(const BigInt& x, uint8_t y, BigInt& q_out, uint8_t& r_out)
BigInt ct_modulo(const BigInt& x, const BigInt& y)
{
- if(x.is_negative() || y.is_negative() || y.is_zero())
- throw Invalid_Argument("ct_modulo requires x >= 0 and y > 0");
+ if(y.is_negative() || y.is_zero())
+ throw Invalid_Argument("ct_modulo requires y > 0");
const size_t y_words = y.sig_words();
@@ -140,6 +141,14 @@ BigInt ct_modulo(const BigInt& x, const BigInt& y)
r.ct_cond_swap(r_gte_y, t);
}
+ if(x.is_negative())
+ {
+ if(r.is_nonzero())
+ {
+ r = y - r;
+ }
+ }
+
return r;
}