summaryrefslogtreecommitdiff
path: root/rw.cpp
diff options
context:
space:
mode:
authorweidai <weidai11@users.noreply.github.com>2007-04-15 22:58:24 +0000
committerweidai <weidai11@users.noreply.github.com>2007-04-15 22:58:24 +0000
commit837bc18cba61043c59a6f46654fba82642592601 (patch)
treedc86942e09832e45e41bc2435f2948afeb5de6cc /rw.cpp
parentbbbd09553b373b5f32f339186ea689132fde21ae (diff)
downloadcryptopp-git-837bc18cba61043c59a6f46654fba82642592601.tar.gz
added blinding and error checking for RW private key operation
Diffstat (limited to 'rw.cpp')
-rw-r--r--rw.cpp42
1 files changed, 28 insertions, 14 deletions
diff --git a/rw.cpp b/rw.cpp
index 2e565496..c1306b39 100644
--- a/rw.cpp
+++ b/rw.cpp
@@ -121,26 +121,40 @@ void InvertibleRWFunction::DEREncode(BufferedTransformation &bt) const
seq.MessageEnd();
}
-Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &in) const
+Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const
{
- // no need to do blinding because RW is only used for signatures
-
DoQuickSanityCheck();
-
- Integer cp=in%m_p, cq=in%m_q;
-
+ ModularArithmetic modn(m_n);
+ Integer r, rInv;
+ do { // do this in a loop for people using small numbers for testing
+ r.Randomize(rng, Integer::One(), m_n - Integer::One());
+ rInv = modn.MultiplicativeInverse(r);
+ } while (rInv.IsZero());
+ Integer re = modn.Square(r);
+ re = modn.Multiply(re, x); // blind
+
+ Integer cp=re%m_p, cq=re%m_q;
if (Jacobi(cp, m_p) * Jacobi(cq, m_q) != 1)
{
- cp = cp%2 ? (cp+m_p) >> 1 : cp >> 1;
- cq = cq%2 ? (cq+m_q) >> 1 : cq >> 1;
+ cp = cp.IsOdd() ? (cp+m_p) >> 1 : cp >> 1;
+ cq = cq.IsOdd() ? (cq+m_q) >> 1 : cq >> 1;
}
- cp = ModularSquareRoot(cp, m_p);
- cq = ModularSquareRoot(cq, m_q);
-
- Integer out = CRT(cq, m_q, cp, m_p, m_u);
-
- return STDMIN(out, m_n-out);
+ #pragma omp parallel
+ #pragma omp sections
+ {
+ #pragma omp section
+ cp = ModularSquareRoot(cp, m_p);
+ #pragma omp section
+ cq = ModularSquareRoot(cq, m_q);
+ }
+
+ Integer y = CRT(cq, m_q, cp, m_p, m_u);
+ y = modn.Multiply(y, rInv); // unblind
+ y = STDMIN(y, m_n-y);
+ if (ApplyFunction(y) != x) // check
+ throw Exception(Exception::OTHER_ERROR, "InvertibleRWFunction: computational error during private key operation");
+ return y;
}
bool InvertibleRWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const