pyflo/pybtc/_secp256k1/module_secp256k1.c
2019-04-17 18:58:27 +04:00

234 lines
8.3 KiB
C

#include <Python.h>
#include <stdio.h>
#include <stdlib.h>
#define USE_NUM_GMP
#include "secp256k1.h"
#include "secp256k1_recovery.h"
secp256k1_context *secp256k1_precomp_context_sign;
secp256k1_context *secp256k1_precomp_context_verify;
static int context_exist = 0;
static PyObject *secp256k1_secp256k1_nonce_rfc6979(PyObject *self, PyObject *args) {
unsigned char nonce[32];
Py_buffer msg32;
Py_buffer key32;
unsigned int counter;
if (!PyArg_ParseTuple(args,"y*y*b", &msg32, &key32, &counter)) { return NULL; }
int r = secp256k1_nonce_function_rfc6979(nonce, msg32.buf, key32.buf, NULL, NULL, counter);
if (r == 0 ) { return Py_BuildValue("b", 0); }
return Py_BuildValue("y#", &nonce, 32);
}
static PyObject *secp256k1_secp256k1_ecdsa_recover(PyObject *self, PyObject *args) {
Py_buffer message;
Py_buffer sig;
int rec_id;
int compressed;
if (!PyArg_ParseTuple(args,"y*y*ii", &sig, &message, &rec_id, &compressed)) { return NULL; }
secp256k1_ecdsa_signature signature;
int r = secp256k1_ecdsa_signature_parse_der(secp256k1_context_no_precomp,
&signature,
sig.buf, sig.len);
if (r != 1) { return Py_BuildValue("b", -1);}
unsigned char compact_sig[64] ;
r = secp256k1_ecdsa_signature_serialize_compact(secp256k1_context_no_precomp,
compact_sig,
&signature);
if (r != 1) { return Py_BuildValue("b", -1);}
secp256k1_ecdsa_recoverable_signature signature_recoverable;
r = secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_no_precomp,
&signature_recoverable,
compact_sig,
rec_id);
if (r != 1) { return Py_BuildValue("b", -2);}
secp256k1_pubkey pubkey;
r = secp256k1_ecdsa_recover(secp256k1_precomp_context_verify,
&pubkey,
&signature_recoverable, message.buf);
if (r != 1) { return Py_BuildValue("b", 0);}
size_t outl;
if (compressed == 1) {
outl = 33;
compressed = SECP256K1_EC_COMPRESSED;
} else {
outl = 65;
compressed = SECP256K1_EC_UNCOMPRESSED;
}
unsigned char pubkeyo[outl];
r = secp256k1_ec_pubkey_serialize(secp256k1_context_no_precomp, pubkeyo, &outl, &pubkey, compressed);
if (r != 1) {
return Py_BuildValue("b", -3);
}
return Py_BuildValue("y#", pubkeyo, outl);
}
static PyObject *secp256k1_secp256k1_ecdsa_verify(PyObject *self, PyObject *args) {
Py_buffer message;
Py_buffer pub;
Py_buffer sig;
if (!PyArg_ParseTuple(args,"y*y*y*", &sig, &pub, &message)) { return NULL; }
secp256k1_ecdsa_signature signature;
secp256k1_pubkey pubkey;
int r = secp256k1_ecdsa_signature_parse_der(secp256k1_context_no_precomp,
&signature,
sig.buf, sig.len);
if (r != 1) { return Py_BuildValue("b", -1);}
r = secp256k1_ec_pubkey_parse(secp256k1_context_no_precomp,
&pubkey,
pub.buf, pub.len);
if (r != 1) { return Py_BuildValue("b", -2);}
r = secp256k1_ecdsa_verify(secp256k1_precomp_context_verify,
&signature,
message.buf,
&pubkey);
if (r != 1) { return Py_BuildValue("b", 0);}
return Py_BuildValue("b", 1);
}
static PyObject *secp256k1_secp256k1_context_create(PyObject *self, PyObject *args) {
if (context_exist == 0 ) {
secp256k1_context *s = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
secp256k1_context *v = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
secp256k1_precomp_context_sign = s;
secp256k1_precomp_context_verify = v;
context_exist = 1;
return Py_BuildValue("b", 1);
}
return Py_BuildValue("b", 0);
}
static PyObject *secp256k1_secp256k1_context_randomize(PyObject *self, PyObject *args) {
Py_buffer buffer;
if (!PyArg_ParseTuple(args,"y*", &buffer)) { return NULL; }
int r = 0;
r += secp256k1_context_randomize(secp256k1_precomp_context_sign, buffer.buf);
r += secp256k1_context_randomize(secp256k1_precomp_context_sign, buffer.buf);
if (r == 2) { r = 1; } else { r = 0; }
return Py_BuildValue("b", r);
}
static PyObject *secp256k1_secp256k1_ec_pubkey_create(PyObject *self, PyObject *args) {
Py_buffer buffer;
int flag;
if (!PyArg_ParseTuple(args,"y*i", &buffer, &flag)) {
return NULL;
}
secp256k1_pubkey pubkey;
int r = 0;
r = secp256k1_ec_pubkey_create(secp256k1_precomp_context_sign, &pubkey, buffer.buf);
if (r != 1) {
return Py_BuildValue("b", 0);
}
size_t outl;
if (flag == 1) {
outl = 33;
flag = SECP256K1_EC_COMPRESSED;
} else {
outl = 65;
flag = SECP256K1_EC_UNCOMPRESSED;
}
unsigned char pubkeyo[outl];
r = secp256k1_ec_pubkey_serialize(secp256k1_context_no_precomp, pubkeyo, &outl, &pubkey, flag);
if (r != 1) {
return Py_BuildValue("b", 0);
}
return Py_BuildValue("y#", pubkeyo, outl);
}
static PyObject *secp256k1_secp256k1_ecdsa_sign(PyObject *self, PyObject *args) {
Py_buffer msg;
Py_buffer private_key;
int der_encoding;
if (!PyArg_ParseTuple(args,"y*y*b", &msg, &private_key, &der_encoding)) {
return NULL;
}
secp256k1_ecdsa_recoverable_signature signature;
int r=1;
r = secp256k1_ecdsa_sign_recoverable(secp256k1_precomp_context_sign,
&signature,
msg.buf,
private_key.buf,
NULL, NULL);
if (r != 1) {
return Py_BuildValue("b", 0);
}
if (der_encoding == 0) {
return Py_BuildValue("y#", &signature, 65);
} else {
unsigned char outputSer[72];
size_t outputLen = 72;
secp256k1_ecdsa_signature_serialize_der(secp256k1_context_no_precomp,
outputSer,
&outputLen,
(const secp256k1_ecdsa_signature *)&signature);
return Py_BuildValue("y#", &outputSer, outputLen);
}
}
static PyMethodDef module_methods[] = {
{"secp256k1_context_randomize", secp256k1_secp256k1_context_randomize, METH_VARARGS, "Randomize context"},
{"secp256k1_context_create", secp256k1_secp256k1_context_create, METH_VARARGS, "Returns context"},
{"secp256k1_ec_pubkey_create", secp256k1_secp256k1_ec_pubkey_create, METH_VARARGS, "Returns public key"},
{"secp256k1_ecdsa_sign", secp256k1_secp256k1_ecdsa_sign, METH_VARARGS, "Sign message"},
{"secp256k1_ecdsa_verify", secp256k1_secp256k1_ecdsa_verify, METH_VARARGS, "Verify signature"},
{"secp256k1_ecdsa_recover", secp256k1_secp256k1_ecdsa_recover, METH_VARARGS, "Recover public key from signature"},
{"secp256k1_nonce_rfc6979", secp256k1_secp256k1_nonce_rfc6979, METH_VARARGS, "Create rfc6979 nonce"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef _module_secp256k1 = {
PyModuleDef_HEAD_INIT,
"_secp256k1",
"...",
-1,
module_methods
};
PyMODINIT_FUNC PyInit__secp256k1(void) {
PyObject *m;
m = PyModule_Create(&_module_secp256k1);
PyModule_AddObject(m, "SECP256K1_CONTEXT_NO_PRECOMP", PyCapsule_New(&secp256k1_context_no_precomp,
"secp256k1_context", NULL));
PyModule_AddIntMacro(m, SECP256K1_CONTEXT_VERIFY);
PyModule_AddIntMacro(m, SECP256K1_CONTEXT_SIGN);
PyModule_AddIntMacro(m, SECP256K1_CONTEXT_NONE);
PyModule_AddIntMacro(m, SECP256K1_EC_COMPRESSED);
PyModule_AddIntMacro(m, SECP256K1_EC_UNCOMPRESSED);
PyModule_AddIntMacro(m, SECP256K1_TAG_PUBKEY_EVEN);
PyModule_AddIntMacro(m, SECP256K1_TAG_PUBKEY_ODD);
PyModule_AddIntMacro(m, SECP256K1_TAG_PUBKEY_UNCOMPRESSED);
PyModule_AddIntMacro(m, SECP256K1_TAG_PUBKEY_HYBRID_EVEN);
PyModule_AddIntMacro(m, SECP256K1_TAG_PUBKEY_HYBRID_ODD);
return m;
}