-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crypto: speed up secp256k1/field.py (#160)
* Speed up crypto/secp256k1/field.py by 100x (!) using Cython. * Fill in the build.py docstring, adjust data types in field.pxd per review. * Update a secp256k1 mention in the decred package's README.md . * Stop the build from failing when a C compiler cannot be found.
- Loading branch information
Showing
9 changed files
with
339 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
decred/examples/wallets | ||
decred/dist | ||
tinywallet/dist | ||
decred/dist/ | ||
decred/poetry.lock | ||
tinywallet/dist/ | ||
htmlcov/ | ||
prof/ | ||
.venv/ | ||
__pycache__/ | ||
.pytest_cache | ||
.coverage | ||
.venv | ||
*.so | ||
*.dll | ||
*.html | ||
*.egg-info | ||
*.sublime-project | ||
*.sublime-workspace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
""" | ||
Copyright (c) 2020, The Decred developers | ||
See LICENSE for details | ||
This file implements Cython integration (see https://cython.org/) to generate | ||
a C extension that speeds up the low-level secp256k1 crypto code. This is used | ||
by the Poetry tool when generating the wheel archive via its `build` command. | ||
It uses a currently undocumented Poetry feature, see: | ||
https://github.com/python-poetry/poetry/issues/11#issuecomment-379484540 | ||
If Cython or a C compiler cannot be found, we skip the compilation | ||
of the C extension, and the Python code will be used. | ||
The shared library can also be built manually using the command: | ||
$ cythonize -X language_level=3 -a -i ./decred/crypto/secp256k1/field.py | ||
""" | ||
|
||
from distutils.command.build_ext import build_ext | ||
|
||
|
||
class BuildExt(build_ext): | ||
def build_extensions(self): | ||
try: | ||
super().build_extensions() | ||
except Exception: | ||
pass | ||
|
||
|
||
def build(setup_kwargs): | ||
try: | ||
from Cython.Build import cythonize | ||
|
||
setup_kwargs.update( | ||
dict( | ||
ext_modules=cythonize(["decred/crypto/secp256k1/field.py"]), | ||
cmdclass=dict(build_ext=BuildExt), | ||
) | ||
) | ||
except Exception: | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
""" | ||
Copyright (c) 2020, The Decred developers | ||
See LICENSE for details | ||
Definitions allowing Cython to generate optimized C code that builds a | ||
dynamic library speeding up the field.py code. | ||
""" | ||
|
||
import cython | ||
|
||
|
||
cdef unsigned long twoBitsMask = 0x03 | ||
cdef unsigned long fourBitsMask = 0x0F | ||
cdef unsigned long sixBitsMask = 0x3F | ||
cdef unsigned long eightBitsMask = 0xFF | ||
cdef unsigned long fieldWords = 10 | ||
cdef unsigned long fieldBase = 26 | ||
cdef unsigned long fieldBaseMask = (1 << fieldBase) - 1 | ||
cdef unsigned long fieldMSBBits = 256 - (fieldBase * (fieldWords - 1)) | ||
cdef unsigned long fieldMSBMask = (1 << fieldMSBBits) - 1 | ||
cdef unsigned long fieldPrimeWordZero = 0x3FFFC2F | ||
cdef unsigned long fieldPrimeWordOne = 0x3FFFFBF | ||
cdef unsigned long primePartBy16 = 68719492368 | ||
|
||
|
||
cdef class FieldVal: | ||
cdef public unsigned long n[10] | ||
|
||
@cython.locals( | ||
m=cython.ulong, | ||
t0=cython.ulong, | ||
t1=cython.ulong, | ||
t2=cython.ulong, | ||
t3=cython.ulong, | ||
t4=cython.ulong, | ||
t5=cython.ulong, | ||
t6=cython.ulong, | ||
t7=cython.ulong, | ||
t8=cython.ulong, | ||
t9=cython.ulong, | ||
) | ||
cpdef normalize(self) | ||
|
||
cpdef negateVal(self, FieldVal val, unsigned long magnitude) | ||
|
||
cpdef add(self, FieldVal val) | ||
|
||
@cython.locals( | ||
m=cython.ulong, | ||
n=cython.ulong, | ||
t0=cython.ulong, | ||
t1=cython.ulong, | ||
t2=cython.ulong, | ||
t3=cython.ulong, | ||
t4=cython.ulong, | ||
t5=cython.ulong, | ||
t6=cython.ulong, | ||
t7=cython.ulong, | ||
t8=cython.ulong, | ||
t9=cython.ulong, | ||
t10=cython.ulong, | ||
t11=cython.ulong, | ||
t12=cython.ulong, | ||
t13=cython.ulong, | ||
t14=cython.ulong, | ||
t15=cython.ulong, | ||
t16=cython.ulong, | ||
t17=cython.ulong, | ||
t18=cython.ulong, | ||
t19=cython.ulong, | ||
) | ||
cpdef squareVal(self, FieldVal val) | ||
|
||
cpdef mulInt(self, long val) | ||
|
||
@cython.locals( | ||
d=cython.ulong, | ||
m=cython.ulong, | ||
t0=cython.ulong, | ||
t1=cython.ulong, | ||
t2=cython.ulong, | ||
t3=cython.ulong, | ||
t4=cython.ulong, | ||
t5=cython.ulong, | ||
t6=cython.ulong, | ||
t7=cython.ulong, | ||
t8=cython.ulong, | ||
t9=cython.ulong, | ||
t10=cython.ulong, | ||
t11=cython.ulong, | ||
t12=cython.ulong, | ||
t13=cython.ulong, | ||
t14=cython.ulong, | ||
t15=cython.ulong, | ||
t16=cython.ulong, | ||
t17=cython.ulong, | ||
t18=cython.ulong, | ||
t19=cython.ulong, | ||
) | ||
cpdef mul2(self, FieldVal val, FieldVal val2) | ||
|
||
cpdef add2(self, FieldVal val, FieldVal val2) | ||
|
||
cpdef putBytes(self, char b[32]) | ||
|
||
# inverse relies heavily on FieldVal methods, preventing optimization. | ||
# @cython.locals( | ||
# a2=FieldVal, | ||
# a3=FieldVal, | ||
# a4=FieldVal, | ||
# a10=FieldVal, | ||
# a11=FieldVal, | ||
# a21=FieldVal, | ||
# a42=FieldVal, | ||
# a45=FieldVal, | ||
# a63=FieldVal, | ||
# a1019=FieldVal, | ||
# a1023=FieldVal, | ||
# ) | ||
# cpdef inverse(self) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.