Skip to content

Commit b1568d4

Browse files
committed
also allow the older gmpy
since on older distros like CentOS 6 there is python-gmpy but not python-gmpy2, support gmpy too
1 parent 4403ec3 commit b1568d4

File tree

6 files changed

+80
-21
lines changed

6 files changed

+80
-21
lines changed

.travis.yml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ language: python
66
cache: pip
77
addons:
88
apt_packages:
9-
# needed for gmpy2
9+
# needed for gmpy and gmpy2
1010
- libgmp-dev
1111
- libmpfr-dev
1212
- libmpc-dev
@@ -24,7 +24,9 @@ matrix:
2424
- python: 2.7
2525
env: TOX_ENV=py27_old_six
2626
- python: 2.7
27-
env: TOX_ENV=gmppy27
27+
env: TOX_ENV=gmpypy27
28+
- python: 2.7
29+
env: TOX_ENV=gmpy2py27
2830
- python: 3.3
2931
env: TOX_ENV=py33
3032
- python: 3.4
@@ -42,7 +44,11 @@ matrix:
4244
dist: xenial
4345
sudo: true
4446
- python: 3.8
45-
env: TOX_ENV=gmppy38
47+
env: TOX_ENV=gmpypy38
48+
dist: xenial
49+
sudo: true
50+
- python: 3.8
51+
env: TOX_ENV=gmpy2py38
4652
dist: xenial
4753
sudo: true
4854
- python: nightly
@@ -87,12 +93,15 @@ install:
8793
else
8894
travis_retry pip install -r build-requirements.txt;
8995
fi
90-
- if [[ $TOX_ENV =~ gmp ]]; then travis_retry pip install gmpy2; fi
96+
- if [[ $TOX_ENV =~ gmpy2 ]]; then travis_retry pip install gmpy2; fi
97+
- if [[ $TOX_ENV =~ gmpyp ]]; then travis_retry pip install gmpy; fi
9198
- if [[ $INSTRUMENTAL ]]; then travis_retry pip install instrumental; fi
9299
- pip list
93100
script:
94101
- if [[ $TOX_ENV ]]; then tox -e $TOX_ENV; fi
95-
- if [[ $TOX_ENV =~ gmp ]]; then tox -e speedgmp2; else tox -e speed; fi
102+
- if [[ $TOX_ENV =~ gmpy2 ]]; then tox -e speedgmpy2; fi
103+
- if [[ $TOX_ENV =~ gmpyp ]]; then tox -e speedgmpy; fi
104+
- if ! [[ $TOX_ENV =~ gmpy ]]; then tox -e speed; fi
96105
- |
97106
if [[ $INSTRUMENTAL && $TRAVIS_PULL_REQUEST != "false" ]]; then
98107
git checkout $PR_FIRST^

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ This library uses only Python and the 'six' package. It is compatible with
3434
Python 2.6, 2.7 and 3.3+. It also supports execution on the alternative
3535
implementations like pypy and pypy3.
3636

37-
If `gmpy2` is installed, it will be used for faster arithmetic.
38-
`gmpy2` can be installed after this library is installed, `python-ecdsa` will
39-
detect presence of `gmpy2` on start-up and use it automatically.
37+
If `gmpy2` or `gmpy` is installed, they will be used for faster arithmetic.
38+
Either of them can be installed after this library is installed,
39+
`python-ecdsa` will detect their presence on start-up and use them
40+
automatically.
4041

4142
To run the OpenSSL compatibility tests, the 'openssl' tool must be in your
4243
`PATH`. This release has been tested successfully against OpenSSL 0.9.8o,
@@ -58,6 +59,11 @@ it's possible to specify installation together with `gmpy2`:
5859
pip install ecdsa[gmpy2]
5960
```
6061

62+
or (slower, legacy option):
63+
```
64+
pip install ecdsa[gmpy]
65+
```
66+
6167
## Speed
6268

6369
The following table shows how long this library takes to generate keypairs
@@ -87,7 +93,7 @@ On an Intel Core i7 4790K @ 4.0GHz I'm getting the following performance:
8793
BRAINPOOLP384r1: 96 0.00112s 892.44 0.00119s 841.48 0.00229s 436.71
8894
BRAINPOOLP512r1: 128 0.00214s 467.05 0.00226s 441.64 0.00422s 237.13
8995
```
90-
To test performance with `gmpy2` loaded, use `tox -e speedgmp2`.
96+
To test performance with `gmpy2` loaded, use `tox -e speedgmpy2`.
9197
On the same machine I'm getting the following performance with `gmpy2`:
9298
```
9399
siglen keygen keygen/s sign sign/s verify verify/s
@@ -106,6 +112,8 @@ On the same machine I'm getting the following performance with `gmpy2`:
106112
BRAINPOOLP512r1: 128 0.00062s 1618.30 0.00063s 1577.42 0.00125s 799.29
107113
```
108114

115+
(there's also `gmpy` version, execute it using `tox -e speedgmpy`)
116+
109117
For comparison, a highly optimised implementation (including curve-specific
110118
assembly for some curves), like the one in OpenSSL, provides following
111119
performance numbers on the same machine.

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@
4343
install_requires=['six>=1.9.0'],
4444
extras_require={
4545
'gmpy2': 'gmpy2',
46+
'gmpy': 'gmpy',
4647
},
4748
)

src/ecdsa/ellipticcurve.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,14 @@
3737

3838
try:
3939
from gmpy2 import mpz
40-
GMPY2=True
40+
GMPY=True
4141
except ImportError:
42-
GMPY2=False
42+
try:
43+
from gmpy import mpz
44+
GMPY=True
45+
except ImportError:
46+
GMPY=False
47+
4348

4449
from six import python_2_unicode_compatible
4550
from . import numbertheory
@@ -49,7 +54,7 @@
4954
class CurveFp(object):
5055
"""Elliptic Curve over the field of integers modulo a prime."""
5156

52-
if GMPY2:
57+
if GMPY:
5358
def __init__(self, p, a, b, h=None):
5459
"""
5560
The curve of points satisfying y^2 = x^3 + a*x + b (mod p).
@@ -137,7 +142,7 @@ def __init__(self, curve, x, y, z, order=None, generator=False):
137142
cause to precompute multiplication table for it
138143
"""
139144
self.__curve = curve
140-
if GMPY2:
145+
if GMPY:
141146
self.__x = mpz(x)
142147
self.__y = mpz(y)
143148
self.__z = mpz(z)
@@ -573,7 +578,7 @@ class Point(object):
573578
def __init__(self, curve, x, y, order=None):
574579
"""curve, x, y, order; order (optional) is the order of this point."""
575580
self.__curve = curve
576-
if GMPY2:
581+
if GMPY:
577582
self.__x = x and mpz(x)
578583
self.__y = y and mpz(y)
579584
self.__order = order and mpz(order)

src/ecdsa/numbertheory.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@
2020
try:
2121
from gmpy2 import powmod
2222
GMPY2=True
23+
GMPY=False
2324
except ImportError:
2425
GMPY2=False
26+
try:
27+
from gmpy import mpz
28+
GMPY=True
29+
except ImportError:
30+
GMPY=False
2531

2632
import math
2733
import warnings
@@ -212,6 +218,25 @@ def inverse_mod(a, m):
212218
if a == 0:
213219
return 0
214220
return powmod(a, -1, m)
221+
elif GMPY:
222+
def inverse_mod(a, m):
223+
"""Inverse of a mod m."""
224+
# while libgmp likely does support inverses modulo, it is accessible
225+
# only using the native `pow()` function, and `pow()` sanity checks
226+
# the parameters before passing them on to underlying implementation
227+
# on Python2
228+
if a == 0:
229+
return 0
230+
a = mpz(a)
231+
m = mpz(m)
232+
233+
lm, hm = mpz(1), mpz(0)
234+
low, high = a % m, m
235+
while low > 1:
236+
r = high // low
237+
lm, low, hm, high = hm - lm * r, high - low * r, lm, low
238+
239+
return lm % m
215240
else:
216241
def inverse_mod(a, m):
217242
"""Inverse of a mod m."""

tox.ini

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
[tox]
3-
envlist = py26, py27, py33, py34, py35, py36, py37, py38, py, pypy, pypy3, gmppy27, gmppy38
3+
envlist = py26, py27, py33, py34, py35, py36, py37, py38, py, pypy, pypy3, gmpy2py27, gmpy2py38, gmpypy27, gmpypy38
44

55
[testenv]
66
deps =
@@ -12,9 +12,10 @@ deps =
1212
py{26}: hypothesis<3
1313
py{26,27,34,35,36,37,38,py,py3}: pytest
1414
py{27,34,35,36,37,38,py,py3}: hypothesis
15-
gmppy{27,38}: gmpy2
16-
gmppy{27,38}: pytest
17-
gmppy{27,38}: hypothesis
15+
gmpy2py{27,38}: gmpy2
16+
gmpypy{27,38}: gmpy
17+
gmpy{2py27,2py38,py27,py38}: pytest
18+
gmpy{2py27,2py38,py27,py38}: hypothesis
1819
# six==1.9.0 comes from setup.py install_requires
1920
py27_old_six: six==1.9.0
2021
py27_old_six: pytest
@@ -28,10 +29,16 @@ commands = coverage run --branch -m pytest {posargs:src/ecdsa}
2829
[testenv:py27_old_six]
2930
basepython = python2.7
3031

31-
[testenv:gmppy27]
32+
[testenv:gmpypy27]
3233
basepython=python2.7
3334

34-
[testenv:gmppy38]
35+
[testenv:gmpypy38]
36+
basepython=python3.8
37+
38+
[testenv:gmpy2py27]
39+
basepython=python2.7
40+
41+
[testenv:gmpy2py38]
3542
basepython=python3.8
3643

3744
[testenv:coverage]
@@ -41,7 +48,11 @@ commands = coverage run --branch -m pytest --hypothesis-show-statistics {posargs
4148
[testenv:speed]
4249
commands = {envpython} speed.py
4350

44-
[testenv:speedgmp2]
51+
[testenv:speedgmpy]
52+
deps = gmpy
53+
commands = {envpython} speed.py
54+
55+
[testenv:speedgmpy2]
4556
deps = gmpy2
4657
commands = {envpython} speed.py
4758

0 commit comments

Comments
 (0)