From 92c7422d851e0b654a31bdc0fd3dc415a3b8f45d Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Sun, 6 Oct 2019 20:26:52 +0200 Subject: [PATCH] use sliding window for precomputation --- src/ecdsa/ellipticcurve.py | 43 +++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/ecdsa/ellipticcurve.py b/src/ecdsa/ellipticcurve.py index ff6fcd7e..07c79cbc 100644 --- a/src/ecdsa/ellipticcurve.py +++ b/src/ecdsa/ellipticcurve.py @@ -36,6 +36,20 @@ from six import python_2_unicode_compatible from . import numbertheory +import binascii + + +def orderlen(order): + return (1+len("%x" % order))//2 # bytes + + +def number_to_string(num, order): + l = orderlen(order) + fmt_str = "%0" + str(2 * l) + "x" + string = binascii.unhexlify((fmt_str % num).encode()) + assert len(string) == l, (len(string), l) + return string + @python_2_unicode_compatible class CurveFp(object): @@ -73,16 +87,9 @@ def __init__(self, curve, x, y, z, order=None, generator=False): self.__order = order self.__precompute={} if generator: - assert order - i = 1 - doubler = PointJacobi(curve, x, y, z, order) - self.__precompute[i] = doubler - doubler = doubler.double().normalise() - - while i < order: - i *= 2 - self.__precompute[i] = doubler - doubler = doubler.double().normalise() + point = PointJacobi(curve, x, y, z, order) + for i in range(1, 256): + self.__precompute[i] = (point * i).normalise() def __eq__(self, other): """Compare two points with each-other.""" @@ -244,13 +251,15 @@ def __rmul__(self, other): def _mul_precompute(self, other): i = 1 result = None - while i <= other: - if i & other: - if result: - result = result + self.__precompute[i] - else: - result = self.__precompute[i] - i *= 2 + bit_mask = number_to_string(other, other) + bit_mask = bytearray(bit_mask) + result = self.__precompute[bit_mask[0]] + for b in bit_mask[1:]: + for _ in range(8): + result = result.double() + if b: + result = result + self.__precompute[b] + return result def __mul__(self, other):