summaryrefslogtreecommitdiff
path: root/integer.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2018-03-25 00:43:21 -0400
committerGitHub <noreply@github.com>2018-03-25 00:43:21 -0400
commitff82b5a886d379899f8a4eb142c4fefb057e19c0 (patch)
tree1f55b81b448c44dc48140a41a4ce8fc3a30bee16 /integer.cpp
parentb0f71705955698cf1e0d1101dbe6430566b70b63 (diff)
downloadcryptopp-git-ff82b5a886d379899f8a4eb142c4fefb057e19c0.tar.gz
Fix incorrect InverseMod (GH #602) (#603)
Diffstat (limited to 'integer.cpp')
-rw-r--r--integer.cpp20
1 files changed, 17 insertions, 3 deletions
diff --git a/integer.cpp b/integer.cpp
index e9846bde..cf6c6ee9 100644
--- a/integer.cpp
+++ b/integer.cpp
@@ -4380,7 +4380,20 @@ Integer Integer::InverseMod(const Integer &m) const
CRYPTOPP_ASSERT(m.NotNegative());
if (IsNegative())
- return Modulo(m).InverseMod(m);
+ return Modulo(m).InverseModNext(m);
+
+ // Place *this in the range [0, 2m-1]
+ // http://github.com/weidai11/cryptopp/issues/602
+ if (*this >= (m << 1))
+ return Modulo(m).InverseModNext(m);
+
+ return InverseModNext(m);
+}
+
+Integer Integer::InverseModNext(const Integer &m) const
+{
+ CRYPTOPP_ASSERT(m.NotNegative());
+ CRYPTOPP_ASSERT(*this < 2*m);
if (m.IsEven())
{
@@ -4389,11 +4402,12 @@ Integer Integer::InverseMod(const Integer &m) const
if (*this == One())
return One();
- Integer u = m.Modulo(*this).InverseMod(*this);
+ Integer u = m.Modulo(*this).InverseModNext(*this);
return !u ? Zero() : (m*(*this-u)+1)/(*this);
}
- SecBlock<word> T(m.reg.size() * 4);
+ // AlmostInverse requires a 4x workspace
+ IntegerSecBlock T(m.reg.size() * 4);
Integer r((word)0, m.reg.size());
unsigned k = AlmostInverse(r.reg, T, reg, reg.size(), m.reg, m.reg.size());
DivideByPower2Mod(r.reg, r.reg, k, m.reg, m.reg.size());