Browse Source

Version 0.8.6

New features/improvements:

	* Address generation using secp256k1 library (Linux only)

Instructions for installing the secp256k1 library on your system:

	doc/wiki/install-linux/Install-MMGen-on-Debian-or-Ubuntu-Linux.md

If secp256k1 is not installed on the system, MMGen remains usable. It just falls
back to 'keyconv', or failing that, python-ecdsa for generating addresses.
philemon 8 years ago
parent
commit
0be6059674
4 changed files with 52 additions and 25 deletions
  1. 45 19
      extmod/secp256k1mod.c
  2. 1 1
      mmgen/globalvars.py
  3. 4 3
      setup.py
  4. 2 2
      test/gentest.py

+ 45 - 19
extmod/secp256k1mod.c

@@ -1,35 +1,61 @@
+/*
+  mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
+  Copyright (C)2013-2016 Philemon <mmgen-py@yandex.com>
+
+  This program is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+  details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #include <Python.h>
 #include <Python.h>
 #include <secp256k1.h>
 #include <secp256k1.h>
 
 
 static PyObject * priv2pub(PyObject *self, PyObject *args) {
 static PyObject * priv2pub(PyObject *self, PyObject *args) {
-    const unsigned char * privkey;
-    const int klen;
-    const int compressed;
-    if (!PyArg_ParseTuple(args, "t#I", &privkey, &klen, &compressed))
-        return NULL;
-    if (klen != 32) return NULL;
-    secp256k1_pubkey pubkey;
-    size_t pubkeyclen = compressed == 1 ? 33: 65;
-    unsigned char pubkeyc[pubkeyclen];
+	const unsigned char * privkey;
+	const int klen;
+	const int compressed;
+	if (!PyArg_ParseTuple(args, "t#I", &privkey, &klen, &compressed))
+		return NULL;
+	if (klen != 32) {
+		PyErr_SetString(PyExc_ValueError, "Private key length not 32 bytes");
+		return NULL;
+	}
+	secp256k1_pubkey pubkey;
+	size_t pubkeyclen = compressed == 1 ? 33: 65;
+	unsigned char pubkeyc[pubkeyclen];
 	static secp256k1_context *ctx = NULL;
 	static secp256k1_context *ctx = NULL;
 	if (ctx == NULL) {
 	if (ctx == NULL) {
 	/*	puts ("Initializing context"); */
 	/*	puts ("Initializing context"); */
 		ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
 		ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
 	}
 	}
-    if (secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) != 1) return NULL;
-    if (secp256k1_ec_pubkey_serialize(ctx, pubkeyc, &pubkeyclen, &pubkey,
-			compressed == 1 ? SECP256K1_EC_COMPRESSED: SECP256K1_EC_UNCOMPRESSED) != 1)
-				return NULL;
-    return Py_BuildValue("s#", pubkeyc,pubkeyclen);
+	if (secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) != 1) {
+		PyErr_SetString(PyExc_RuntimeError, "Public key creation failed");
+		return NULL;
+	}
+	if (secp256k1_ec_pubkey_serialize(ctx, pubkeyc, &pubkeyclen, &pubkey,
+			compressed == 1 ? SECP256K1_EC_COMPRESSED: SECP256K1_EC_UNCOMPRESSED) != 1) {
+		PyErr_SetString(PyExc_RuntimeError, "Public key serialization failed");
+		return NULL;
+	}
+	return Py_BuildValue("s#", pubkeyc,pubkeyclen);
 }
 }
 
 
 static PyMethodDef secp256k1Methods[] = {
 static PyMethodDef secp256k1Methods[] = {
-    {"priv2pub", priv2pub, METH_VARARGS, "Generate pubkey from privkey using libsecp256k1"},
-    {NULL, NULL, 0, NULL} /* Sentinel */
+	{"priv2pub", priv2pub, METH_VARARGS, "Generate pubkey from privkey using libsecp256k1"},
+	{NULL, NULL, 0, NULL} /* Sentinel */
 };
 };
 
 
 PyMODINIT_FUNC initsecp256k1(void) {
 PyMODINIT_FUNC initsecp256k1(void) {
-    PyObject *m;
-    m = Py_InitModule("secp256k1", secp256k1Methods);
-    if (m == NULL) return;
+	PyObject *m;
+	m = Py_InitModule("secp256k1", secp256k1Methods);
+	if (m == NULL) return;
 }
 }

+ 1 - 1
mmgen/globalvars.py

@@ -51,7 +51,7 @@ prog_name = os.path.basename(sys.argv[0])
 author    = 'Philemon'
 author    = 'Philemon'
 email     = '<mmgen-py@yandex.com>'
 email     = '<mmgen-py@yandex.com>'
 Cdates    = '2013-2016'
 Cdates    = '2013-2016'
-version   = '0.8.6rc1'
+version   = '0.8.6'
 
 
 required_opts = [
 required_opts = [
 	'quiet','verbose','debug','outdir','echo_passphrase','passwd_file',
 	'quiet','verbose','debug','outdir','echo_passphrase','passwd_file',

+ 4 - 3
setup.py

@@ -18,7 +18,7 @@
 
 
 from distutils.core import setup,Extension
 from distutils.core import setup,Extension
 from distutils.command.build_ext import build_ext
 from distutils.command.build_ext import build_ext
-import os
+import sys,os
 from shutil import copy2
 from shutil import copy2
 
 
 # install extension module in repository after building
 # install extension module in repository after building
@@ -45,7 +45,7 @@ module1 = Extension(
 setup(
 setup(
 		name         = 'mmgen',
 		name         = 'mmgen',
 		description  = 'A complete Bitcoin offline/online wallet solution for the command line',
 		description  = 'A complete Bitcoin offline/online wallet solution for the command line',
-		version      = '0.8.6rc1',
+		version      = '0.8.6',
 		author       = 'Philemon',
 		author       = 'Philemon',
 		author_email = 'mmgen-py@yandex.com',
 		author_email = 'mmgen-py@yandex.com',
 		url          = 'https://github.com/mmgen/mmgen',
 		url          = 'https://github.com/mmgen/mmgen',
@@ -53,7 +53,8 @@ setup(
 		platforms    = 'Linux, MS Windows, Raspberry PI',
 		platforms    = 'Linux, MS Windows, Raspberry PI',
 		keywords     = 'Bitcoin, wallet, cold storage, offline storage, open-source, command-line, Python, Bitcoin Core, bitcoind, hd, deterministic, hierarchical, secure, anonymous',
 		keywords     = 'Bitcoin, wallet, cold storage, offline storage, open-source, command-line, Python, Bitcoin Core, bitcoind, hd, deterministic, hierarchical, secure, anonymous',
 		cmdclass     = { 'build_ext': my_build_ext },
 		cmdclass     = { 'build_ext': my_build_ext },
-		ext_modules = [module1],
+		# disable building of secp256k1 extension module on Windows
+		ext_modules = [module1] if sys.platform[:5] == 'linux' else [],
 		py_modules = [
 		py_modules = [
 			'mmgen.__init__',
 			'mmgen.__init__',
 			'mmgen.addr',
 			'mmgen.addr',

+ 2 - 2
test/gentest.py

@@ -48,8 +48,8 @@ opts_data = {
 as specified by the user:
 as specified by the user:
 
 
     1) with the native Python ecdsa library (very slow)
     1) with the native Python ecdsa library (very slow)
-    2) with the 'keyconv' utility from the 'vanitygen' package (the default)
-    3) using bitcoincore.org's secp256k1 library (very fast, experimental)
+    2) with the 'keyconv' utility from the 'vanitygen' package (old default)
+    3) using bitcoincore.org's secp256k1 library (default from v0.8.6)
 
 
 This test suite compares the output of these different methods against each
 This test suite compares the output of these different methods against each
 other over set of randomly generated secret keys ({snum} by default).
 other over set of randomly generated secret keys ({snum} by default).