Help debugging a bitcoin PHP extension (wrapper for bitcoin/secp256k1)
| From: | Thomas Kerin | Date: | Thu, 19 Mar 2015 17:20:29 +0000 |
| Subject: | Help debugging a bitcoin PHP extension (wrapper for bitcoin/secp256k1) | ||
| Groups: | php.general | ||
| Request: | Send a blank email to php-general+get-324674@lists.php.net to get a copy of this message | ||
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Hi all,
I'm not sure of the best place to ask, but I am wondering if anyone
could look over
an extension I am working on, a wrapper for a small C library used to do
of the
cryptographic operations in bitcoin.
I currently have all but two of the functions written and mostly working
- with tonnes
of positive tests - but it seems there is a segmentation fault in one
of the functions.
I think the problem in how I'm dealing with setting return values to the
reference of an argument.
It's quite a small extension and it hasn't taken a lot of effort to
bring it this far, but
I've stumbled for quite a bit on this. I know more experienced eyes
could root out the
problems quicker than mine.
The repo for this is here: https://github.com/afk11/secp256k1-php
I'd love more eyes to go over it as it blows the alternatives out of the
water - an ECDSA implementation
in pure PHP is quite slow. This is specialized to bitcoins elliptic
curve, it's safer than reimplementing
the wheel, and is insanely fast!
Here is the function which SEGFAULTS, for those short on time (FYI I run
php 5.6)
PHP_FUNCTION(secp256k1_ec_pubkey_decompress) {
secp256k1_start(SECP256K1_START_SIGN);
// We are taking a pubkey, and it's length, and decompressing it
(33 or 65 bytes -> 65 bytes)
// updating both of these zvals at the end
zval *pubkey, *pubkeylen;
unsigned char* newpubkey;
int newpubkeylen;
int result;
// From documentation it seems I can only mess with zvals when
setting by reference?
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz",
&pubkey, &pubkeylen) == FAILURE) {
return;
}
// Initialize an unsigned char* with our pubkey
newpubkey = Z_STRVAL_P(pubkey);
newpubkeylen = Z_LVAL_P(pubkeylen);
result = secp256k1_ec_pubkey_decompress(newpubkey, &newpubkeylen);
if (result == 1) {
newpubkey[newpubkeylen] = 0U;
// Great, it worked, set pubkey and pubkeylen to the new values
ZVAL_STRINGL(pubkey, newpubkey, newpubkeylen, 0);
ZVAL_LONG(pubkeylen, newpubkeylen);
} else {
efree(newpubkey);
}
// Done, return the result.
RETURN_LONG(result);
}
Not sure what it could be, the documentation I've found online often
contains macros not found
in PHP5.6, so it's hard to know what exactly I would be doing.
For reference, the end libraries header is here:
https://github.com/bitcoin/secp256k1/tree/master/include/secp256k1.h
All the best,
- --
Thomas Kerin
- -------------------------
My PGP key can be found here
<http://pgp.mit.edu/pks/lookup?op=get&search=0x3F0D2F83A2966155>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQJ8BAEBCgBmBQJVCwVZXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25zLm9w
ZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXQ2MzI1MzM4QjJGOTU5OEUzREMzQzc0MzAz
RjBEMkY4M0EyOTY2MTU1AAoJED8NL4OilmFVmzUP/jGeLvg+/Q35czpxYY/MTBFI
+cdqOCtMx5cIhI5X3kKUYZOnwEIn9fuiDM+TXmLzwit392YfHC2QZts3F/q25f/P
6IdfGgNNwWbu4JfKPe8MDIrQXVE8wbt9CQ5CvLCtPP/mK/uPuObmOu4KdhJHgYJy
eYkuxysodzHrwJTrR5oE/jBUPKP3ndVI4/r3fQm6snXM7sI2p4P7KkvcgP+NqivC
7HTVn4abGU1AnPzAobAG7WuABfKduWoA1ZNmstISC8KfRYnc50CstSi4r7B32jsK
uykBr0dfoVITpwrA2cAKpS/rmO2vN8O+aABigFy5Vbg4v3LJVF3ZOOLduIPvtcPO
JPxHEDIphnHBvphxAm8vaQII1R6Fjyq0RdQNEmQbTocFcCJcINwV+WeQONgg1+/d
PKYpD7FZF9j+pVo/MAybsLwdwUDxYkvDTmlx+a8MIElM2guCtABdxqOuewq3ZfQ8
865eNKR/CaZ3AmTwuvRjCxOzOguGG/vmJxa/xyiuGuoYvqDBVlW9YsiEDqk7kW1e
XjEivFb1Bn9BxjAt4WK7aiUN6T7jLpRDfsVSWo3BEkVBaSXeAg5OCA4g/9FyJa1Y
foNBKP3psdmK9FcNUSSMITvz7ovssa6FKyr7RrINqTTurZBumZnndKXFwPCYiHmi
zLwodvh12Jm7ltp4UHt5
=oJjR
-----END PGP SIGNATURE-----