Browse Source

secp256k1 extmod: minor cleanups, add private key check

The MMGen Project 11 months ago
parent
commit
5025ed9dc3
1 changed files with 33 additions and 17 deletions
  1. 33 17
      extmod/secp256k1mod.c

+ 33 - 17
extmod/secp256k1mod.c

@@ -20,40 +20,56 @@
 #include <Python.h>
 #include <secp256k1.h>
 
+int privkey_check(
+		const secp256k1_context * ctx,
+		const unsigned char *     privkey_bytes,
+		const Py_ssize_t          privkey_bytes_len,
+		const char *              desc
+	) {
+	if (privkey_bytes_len != 32) {
+		char buf[64 + strlen(desc)];
+		sprintf(buf, "%s length not 32 bytes", desc);
+		PyErr_SetString(PyExc_ValueError, buf);
+		return 0;
+	}
+	if (secp256k1_ec_seckey_verify(ctx, privkey_bytes) != 1) {
+		char buf[64 + strlen(desc)];
+		sprintf(buf, "%s not in allowable range", desc);
+		PyErr_SetString(PyExc_ValueError, buf);
+		return 0;
+	}
+	return 1;
+}
+
 static PyObject * pubkey_gen(PyObject *self, PyObject *args) {
-	const unsigned char * privkey;
-	const int klen;
+	const unsigned char * privkey_bytes;
+	const Py_ssize_t privkey_bytes_len;
 	const int compressed;
-	if (!PyArg_ParseTuple(args, "y#I", &privkey, &klen, &compressed)) {
+	if (!PyArg_ParseTuple(args, "y#I", &privkey_bytes, &privkey_bytes_len, &compressed)) {
 		PyErr_SetString(PyExc_ValueError, "Unable to parse extension mod arguments");
 		return NULL;
 	}
-	if (klen != 32) {
-		PyErr_SetString(PyExc_ValueError, "Private key length not 32 bytes");
-		return NULL;
-	}
+	size_t pubkey_bytes_len = compressed == 1 ? 33 : 65;
+	unsigned char pubkey_bytes[pubkey_bytes_len];
 	secp256k1_pubkey pubkey;
-	size_t pubkeyclen = compressed == 1 ? 33 : 65;
-	unsigned char pubkeyc[pubkeyclen];
-	static secp256k1_context *ctx = NULL;
-	if (ctx == NULL) {
-	/*	puts ("Initializing context"); */
-		ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
-	}
+	secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
 	if (ctx == NULL) {
 		PyErr_SetString(PyExc_RuntimeError, "Context initialization failed");
 		return NULL;
 	}
-	if (secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) != 1) {
+	if (!privkey_check(ctx, privkey_bytes, privkey_bytes_len, "Private key")) {
+		return NULL;
+	}
+	if (secp256k1_ec_pubkey_create(ctx, &pubkey, privkey_bytes) != 1) {
 		PyErr_SetString(PyExc_RuntimeError, "Public key creation failed");
 		return NULL;
 	}
-	if (secp256k1_ec_pubkey_serialize(ctx, pubkeyc, &pubkeyclen, &pubkey,
+	if (secp256k1_ec_pubkey_serialize(ctx, pubkey_bytes, &pubkey_bytes_len, &pubkey,
 			compressed == 1 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED) != 1) {
 		PyErr_SetString(PyExc_RuntimeError, "Public key serialization failed");
 		return NULL;
 	}
-	return Py_BuildValue("y#", pubkeyc,pubkeyclen);
+	return Py_BuildValue("y#", pubkey_bytes, pubkey_bytes_len);
 }
 
 /* https://docs.python.org/3/howto/cporting.html */