Browse Source

let's see

tb
ofek 7 years ago
parent
commit
ecc985c41e
  1. 1
      .travis/build_windows_wheels.sh
  2. 1
      .travis/prepare_windows_build.sh
  3. 235
      coincurve/_windows_libsecp256k1.py
  4. 164
      setup.py

1
.travis/build_windows_wheels.sh

@ -29,3 +29,4 @@ cd ../clean
python setup.py bdist_wheel --plat-tag=win32
mv dist/* ../coincurve/dist/
cd ../coincurve

1
.travis/prepare_windows_build.sh

@ -4,6 +4,7 @@ if [[ "$TRAVIS_OS_NAME" == "linux" && ${BUILD_LINUX_WHEELS} -eq 1 ]]; then
mkdir .hidden
cp * .hidden -R
mkdir .hidden/dist
mv .hidden/coincurve/_windows_libsecp256k1.py .hidden/coincurve/_libsecp256k1.py
mv .hidden ../clean
sudo apt-get install -y mingw-w64
sudo apt-get -f install

235
coincurve/_windows_libsecp256k1.py

@ -0,0 +1,235 @@
import os
from cffi import FFI
ffi = FFI()
base_definitions = """
typedef struct secp256k1_context_struct secp256k1_context;
typedef struct {
unsigned char data[64];
} secp256k1_pubkey;
typedef struct {
unsigned char data[64];
} secp256k1_ecdsa_signature;
typedef int (*secp256k1_nonce_function)(
unsigned char *nonce32,
const unsigned char *msg32,
const unsigned char *key32,
const unsigned char *algo16,
void *data,
unsigned int attempt
);
#define SECP256K1_FLAGS_TYPE_MASK ...
#define SECP256K1_FLAGS_TYPE_CONTEXT ...
#define SECP256K1_FLAGS_TYPE_COMPRESSION ...
#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY ...
#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN ...
#define SECP256K1_FLAGS_BIT_COMPRESSION ...
#define SECP256K1_CONTEXT_VERIFY ...
#define SECP256K1_CONTEXT_SIGN ...
#define SECP256K1_CONTEXT_NONE ...
#define SECP256K1_EC_COMPRESSED ...
#define SECP256K1_EC_UNCOMPRESSED ...
secp256k1_context* secp256k1_context_create(
unsigned int flags
);
secp256k1_context* secp256k1_context_clone(
const secp256k1_context* ctx
);
void secp256k1_context_destroy(
secp256k1_context* ctx
);
void secp256k1_context_set_illegal_callback(
secp256k1_context* ctx,
void (*fun)(const char* message, void* data),
const void* data
);
void secp256k1_context_set_error_callback(
secp256k1_context* ctx,
void (*fun)(const char* message, void* data),
const void* data
);
int secp256k1_ec_pubkey_parse(
const secp256k1_context* ctx,
secp256k1_pubkey* pubkey,
const unsigned char *input,
size_t inputlen
);
int secp256k1_ec_pubkey_serialize(
const secp256k1_context* ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_pubkey* pubkey,
unsigned int flags
);
int secp256k1_ecdsa_signature_parse_compact(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const unsigned char *input64
);
int secp256k1_ecdsa_signature_parse_der(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const unsigned char *input,
size_t inputlen
);
int secp256k1_ecdsa_signature_serialize_der(
const secp256k1_context* ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_ecdsa_signature* sig
);
int secp256k1_ecdsa_signature_serialize_compact(
const secp256k1_context* ctx,
unsigned char *output64,
const secp256k1_ecdsa_signature* sig
);
int secp256k1_ecdsa_verify(
const secp256k1_context* ctx,
const secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const secp256k1_pubkey *pubkey
);
int secp256k1_ecdsa_signature_normalize(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature *sigout,
const secp256k1_ecdsa_signature *sigin
);
extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
extern const secp256k1_nonce_function secp256k1_nonce_function_default;
int secp256k1_ecdsa_sign(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
);
int secp256k1_ec_seckey_verify(
const secp256k1_context* ctx,
const unsigned char *seckey
);
int secp256k1_ec_pubkey_create(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const unsigned char *seckey
);
int secp256k1_ec_privkey_tweak_add(
const secp256k1_context* ctx,
unsigned char *seckey,
const unsigned char *tweak
);
int secp256k1_ec_pubkey_tweak_add(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak
);
int secp256k1_ec_privkey_tweak_mul(
const secp256k1_context* ctx,
unsigned char *seckey,
const unsigned char *tweak
);
int secp256k1_ec_pubkey_tweak_mul(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak
);
int secp256k1_context_randomize(
secp256k1_context* ctx,
const unsigned char *seed32
);
int secp256k1_ec_pubkey_combine(
const secp256k1_context* ctx,
secp256k1_pubkey *out,
const secp256k1_pubkey * const * ins,
size_t n
);
"""
recovery_definitions = """
typedef struct {
unsigned char data[65];
} secp256k1_ecdsa_recoverable_signature;
int secp256k1_ecdsa_recoverable_signature_parse_compact(
const secp256k1_context* ctx,
secp256k1_ecdsa_recoverable_signature* sig,
const unsigned char *input64,
int recid
);
int secp256k1_ecdsa_recoverable_signature_convert(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const secp256k1_ecdsa_recoverable_signature* sigin
);
int secp256k1_ecdsa_recoverable_signature_serialize_compact(
const secp256k1_context* ctx,
unsigned char *output64,
int *recid,
const secp256k1_ecdsa_recoverable_signature* sig
);
int secp256k1_ecdsa_sign_recoverable(
const secp256k1_context* ctx,
secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msg32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
);
int secp256k1_ecdsa_recover(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msg32
);
"""
ecdh_definitions = """
int secp256k1_ecdh(
const secp256k1_context* ctx,
unsigned char *result,
const secp256k1_pubkey *pubkey,
const unsigned char *privkey
);
"""
ffi.cdef(base_definitions)
ffi.cdef(recovery_definitions)
ffi.cdef(ecdh_definitions)
here = os.path.dirname(os.path.abspath(__file__))
lib = ffi.dlopen(os.path.join(here, 'libsecp256k1.dll'))

164
setup.py

@ -29,19 +29,21 @@ except ImportError:
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
from setup_support import absolute, build_flags, has_system_lib
from setup_support import absolute, build_flags, detect_dll, has_system_lib
BUILDING_FOR_WINDOWS = detect_dll()
# Version of libsecp256k1 to download if none exists in the `libsecp256k1`
# directory
LIB_TARBALL_URL = "https://github.com/bitcoin-core/secp256k1/archive/master.tar.gz"
LIB_TARBALL_URL = 'https://github.com/bitcoin-core/secp256k1/archive/master.tar.gz'
# We require setuptools >= 3.3
if [int(i) for i in setuptools_version.split('.')] < [3, 3]:
raise SystemExit(
"Your setuptools version ({}) is too old to correctly install this "
"package. Please upgrade to a newer version (>= 3.3).".format(setuptools_version)
'Your setuptools version ({}) is too old to correctly install this '
'package. Please upgrade to a newer version (>= 3.3).'.format(setuptools_version)
)
# Ensure pkg-config is available
@ -50,19 +52,19 @@ try:
except OSError:
raise SystemExit(
"'pkg-config' is required to install this package. "
"Please see the README for details."
'Please see the README for details.'
)
def download_library(command):
if command.dry_run:
return
libdir = absolute("libsecp256k1")
if os.path.exists(os.path.join(libdir, "autogen.sh")):
libdir = absolute('libsecp256k1')
if os.path.exists(os.path.join(libdir, 'autogen.sh')):
# Library already downloaded
return
if not os.path.exists(libdir):
command.announce("downloading libsecp256k1 source code", level=log.INFO)
command.announce('downloading libsecp256k1 source code', level=log.INFO)
try:
r = urlopen(LIB_TARBALL_URL)
if r.getcode() == 200:
@ -74,11 +76,11 @@ def download_library(command):
shutil.move(dirname, libdir)
else:
raise SystemExit(
"Unable to download secp256k1 library: HTTP-Status: %d",
'Unable to download secp256k1 library: HTTP-Status: %d',
r.getcode()
)
except URLError as ex:
raise SystemExit("Unable to download secp256k1 library: %s",
raise SystemExit('Unable to download secp256k1 library: %s',
ex.message)
@ -105,11 +107,6 @@ else:
bdist_wheel = None
class Distribution(_Distribution):
def has_c_libraries(self):
return not has_system_lib()
class build_clib(_build_clib):
def initialize_options(self):
_build_clib.initialize_options(self)
@ -130,22 +127,22 @@ class build_clib(_build_clib):
return [
absolute(os.path.join(root, filename))
for root, _, filenames in os.walk(absolute("libsecp256k1"))
for root, _, filenames in os.walk(absolute('libsecp256k1'))
for filename in filenames
]
def build_libraries(self, libraries):
raise Exception("build_libraries")
raise Exception('build_libraries')
def check_library_list(self, libraries):
raise Exception("check_library_list")
raise Exception('check_library_list')
def get_library_names(self):
return build_flags('libsecp256k1', 'l', os.path.abspath(self.build_temp))
def run(self):
if has_system_lib():
log.info("Using system library")
log.info('Using system library')
return
build_temp = os.path.abspath(self.build_temp)
@ -156,57 +153,57 @@ class build_clib(_build_clib):
if e.errno != errno.EEXIST:
raise
if not os.path.exists(absolute("libsecp256k1/configure")):
if not os.path.exists(absolute('libsecp256k1/configure')):
# configure script hasn't been generated yet
autogen = absolute("libsecp256k1/autogen.sh")
autogen = absolute('libsecp256k1/autogen.sh')
os.chmod(absolute(autogen), 0o755)
subprocess.check_call(
[autogen],
cwd=absolute("libsecp256k1"),
cwd=absolute('libsecp256k1'),
)
for filename in [
"libsecp256k1/configure",
"libsecp256k1/build-aux/compile",
"libsecp256k1/build-aux/config.guess",
"libsecp256k1/build-aux/config.sub",
"libsecp256k1/build-aux/depcomp",
"libsecp256k1/build-aux/install-sh",
"libsecp256k1/build-aux/missing",
"libsecp256k1/build-aux/test-driver",
'libsecp256k1/configure',
'libsecp256k1/build-aux/compile',
'libsecp256k1/build-aux/config.guess',
'libsecp256k1/build-aux/config.sub',
'libsecp256k1/build-aux/depcomp',
'libsecp256k1/build-aux/install-sh',
'libsecp256k1/build-aux/missing',
'libsecp256k1/build-aux/test-driver',
]:
try:
os.chmod(absolute(filename), 0o755)
except OSError as e:
# some of these files might not exist depending on autoconf version
if e.errno != errno.ENOENT:
# If the error isn't "No such file or directory" something
# If the error isn't 'No such file or directory' something
# else is wrong and we want to know about it
raise
cmd = [
absolute("libsecp256k1/configure"),
"--disable-shared",
"--enable-static",
"--disable-dependency-tracking",
"--with-pic",
"--enable-module-recovery",
"--prefix",
absolute('libsecp256k1/configure'),
'--disable-shared',
'--enable-static',
'--disable-dependency-tracking',
'--with-pic',
'--enable-module-recovery',
'--prefix',
os.path.abspath(self.build_clib),
"--enable-experimental",
"--enable-module-ecdh",
"--enable-endomorphism",
"--with-bignum=gmp",
'--enable-experimental',
'--enable-module-ecdh',
'--enable-endomorphism',
'--with-bignum=gmp',
]
log.debug("Running configure: {}".format(" ".join(cmd)))
log.debug('Running configure: {}'.format(' '.join(cmd)))
subprocess.check_call(
cmd,
cwd=build_temp,
)
subprocess.check_call(["make"], cwd=build_temp)
subprocess.check_call(["make", "install"], cwd=build_temp)
subprocess.check_call(['make'], cwd=build_temp)
subprocess.check_call(['make', 'install'], cwd=build_temp)
self.build_flags['include_dirs'].extend(build_flags('libsecp256k1', 'I', build_temp))
self.build_flags['library_dirs'].extend(build_flags('libsecp256k1', 'L', build_temp))
@ -219,18 +216,18 @@ class build_clib(_build_clib):
class build_ext(_build_ext):
def run(self):
if self.distribution.has_c_libraries():
build_clib = self.get_finalized_command("build_clib")
_build_clib = self.get_finalized_command('build_clib')
self.include_dirs.append(
os.path.join(build_clib.build_clib, "include"),
os.path.join(_build_clib.build_clib, 'include'),
)
self.include_dirs.extend(build_clib.build_flags['include_dirs'])
self.include_dirs.extend(_build_clib.build_flags['include_dirs'])
self.library_dirs.append(
os.path.join(build_clib.build_clib, "lib"),
os.path.join(_build_clib.build_clib, 'lib'),
)
self.library_dirs.extend(build_clib.build_flags['library_dirs'])
self.library_dirs.extend(_build_clib.build_flags['library_dirs'])
self.define = build_clib.build_flags['define']
self.define = _build_clib.build_flags['define']
return _build_ext.run(self)
@ -240,13 +237,41 @@ class develop(_develop):
if not has_system_lib():
raise DistutilsError(
"This library is not usable in 'develop' mode when using the "
"bundled libsecp256k1. See README for details.")
'bundled libsecp256k1. See README for details.')
_develop.run(self)
if BUILDING_FOR_WINDOWS:
class Distribution(_Distribution):
def is_pure(self):
return False
setup_kwargs = dict(
package_data={'coincurve': ['*.dll']},
include_package_data=True,
)
else:
class Distribution(_Distribution):
def has_c_libraries(self):
return not has_system_lib()
setup_kwargs = dict(
setup_requires=['cffi>=1.3.0', 'pytest-runner>=2.6.2'],
ext_package='coincurve',
cffi_modules=['_cffi_build/build.py:ffi'],
cmdclass={
'build_clib': build_clib,
'build_ext': build_ext,
'develop': develop,
'egg_info': egg_info,
'sdist': sdist,
'bdist_wheel': bdist_wheel
}
)
setup(
name="coincurve",
version="1.1.0",
**setup_kwargs,
name='coincurve',
version='1.1.0',
description='Cross-platform Python CFFI bindings for libsecp256k1',
long_description=open('README.md', 'r').read(),
@ -258,35 +283,22 @@ setup(
download_url='https://github.com/ofek/coincurve',
license='MIT',
setup_requires=['cffi>=1.3.0', 'pytest-runner>=2.6.2'],
install_requires=['cffi>=1.3.0'],
tests_require=['pytest>=2.8.7'],
packages=find_packages(exclude=('_cffi_build', '_cffi_build.*', 'libsecp256k1')),
ext_package="coincurve",
cffi_modules=[
"_cffi_build/build.py:ffi"
],
cmdclass={
'build_clib': build_clib,
'build_ext': build_ext,
'develop': develop,
'egg_info': egg_info,
'sdist': sdist,
'bdist_wheel': bdist_wheel
},
distclass=Distribution,
zip_safe=False,
classifiers=[
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Libraries",
"Topic :: Security :: Cryptography"
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries',
'Topic :: Security :: Cryptography'
]
)

Loading…
Cancel
Save