From 3bd6f10e8309c89f890a227455e85bd6ffd8d4da Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 5 Oct 2019 17:52:37 +0200 Subject: [PATCH] Apply nonce bit-length mitigation to stop timing leakage. - See https://minerva.crocs.fi.muni.cz for more info. --- src/ecdsa/ecdsa.py | 11 ++++++++++- src/ecdsa/ellipticcurve.py | 10 ++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/ecdsa/ecdsa.py b/src/ecdsa/ecdsa.py index a7b93614..c293121e 100644 --- a/src/ecdsa/ecdsa.py +++ b/src/ecdsa/ecdsa.py @@ -56,6 +56,7 @@ from six import int2byte, b from . import ellipticcurve from . import numbertheory +from . import rfc6979 class RSZeroError(RuntimeError): @@ -171,7 +172,15 @@ def sign(self, hash, random_k): G = self.public_key.generator n = G.order() k = random_k % n - p1 = k * G + # Fix the bit-length of the random nonce, + # so that it doesn't leak via timing. + # This does not change that ks = k mod n + ks = k + n + kt = ks + n + if rfc6979.bit_length(ks) == rfc6979.bit_length(n): + p1 = kt * G + else: + p1 = ks * G r = p1.x() % n if r == 0: raise RSZeroError("amazingly unlucky random number r") diff --git a/src/ecdsa/ellipticcurve.py b/src/ecdsa/ellipticcurve.py index f1751418..e78314cc 100644 --- a/src/ecdsa/ellipticcurve.py +++ b/src/ecdsa/ellipticcurve.py @@ -86,6 +86,9 @@ def __eq__(self, other): else: return False + def __neg__(self): + return Point(self.__curve, self.__x, self.__curve.p() - self.__y) + def __add__(self, other): """Add one point to another point.""" @@ -123,13 +126,12 @@ def leftmost_bit(x): return result // 2 e = other - if self.__order: - e = e % self.__order - if e == 0: + if e == 0 or (self.__order and e % self.__order == 0): return INFINITY if self == INFINITY: return INFINITY - assert e > 0 + if e < 0: + return (-self) * (-e) # From X9.62 D.3.2: