From e2aeed2e2dd6c9f06e488c2a8a8225096e9400ad Mon Sep 17 00:00:00 2001 From: weidai Date: Sun, 15 Apr 2007 22:58:24 +0000 Subject: [PATCH] added blinding and error checking for RW private key operation --- trunk/c5/rw.cpp | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/trunk/c5/rw.cpp b/trunk/c5/rw.cpp index 2e565496..c1306b39 100644 --- a/trunk/c5/rw.cpp +++ b/trunk/c5/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(); + 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=in%m_p, cq=in%m_q; - + 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); + #pragma omp parallel + #pragma omp sections + { + #pragma omp section + cp = ModularSquareRoot(cp, m_p); + #pragma omp section + cq = ModularSquareRoot(cq, m_q); + } - Integer out = CRT(cq, m_q, cp, m_p, m_u); - - return STDMIN(out, m_n-out); + 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