From 0d5dffad2f1175e9fb714a95b2bf2adb97313906 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Wed, 2 Dec 2020 10:46:43 +0100 Subject: [PATCH] use native inverse modulo when available the builtin pow() can handle negative powers on python 3.8 and later, so do use it --- README.md | 1 + src/ecdsa/numbertheory.py | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index dd38dfed..4db5d574 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ If `gmpy2` or `gmpy` is installed, they will be used for faster arithmetic. Either of them can be installed after this library is installed, `python-ecdsa` will detect their presence on start-up and use them automatically. +You should prefer `gmpy2` on Python3 for optimal performance. To run the OpenSSL compatibility tests, the 'openssl' tool must be in your `PATH`. This release has been tested successfully against OpenSSL 0.9.8o, diff --git a/src/ecdsa/numbertheory.py b/src/ecdsa/numbertheory.py index e5cc888d..5ff1c272 100644 --- a/src/ecdsa/numbertheory.py +++ b/src/ecdsa/numbertheory.py @@ -11,6 +11,7 @@ from __future__ import division +import sys from six import integer_types, PY2 from six.moves import reduce @@ -219,7 +220,7 @@ def square_root_mod_prime(a, p): raise RuntimeError("No b found.") -if GMPY2: +if GMPY2: # pragma: no branch def inverse_mod(a, m): """Inverse of a mod m.""" @@ -228,14 +229,14 @@ def inverse_mod(a, m): return powmod(a, -1, m) -elif GMPY: +elif GMPY: # pragma: no branch def inverse_mod(a, m): """Inverse of a mod m.""" - # while libgmp likely does support inverses modulo, it is accessible - # only using the native `pow()` function, and `pow()` sanity checks - # the parameters before passing them on to underlying implementation - # on Python2 + # while libgmp does support inverses modulo, it is accessible + # only using the native `pow()` function, and `pow()` in gmpy sanity + # checks the parameters before passing them on to underlying + # implementation if a == 0: return 0 a = mpz(a) @@ -250,7 +251,16 @@ def inverse_mod(a, m): return lm % m -else: +elif sys.version_info >= (3, 8): # pragma: no branch + + def inverse_mod(a, m): + """Inverse of a mod m.""" + if a == 0: + return 0 + return pow(a, -1, m) + + +else: # pragma: no branch def inverse_mod(a, m): """Inverse of a mod m."""