-
-
Save scintill/4460738 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// configure the ECC lib | |
if (!defined('USE_EXT')) { | |
if (extension_loaded('gmp')) { | |
define('USE_EXT', 'GMP'); | |
} else if(extension_loaded('bcmath')) { | |
define('USE_EXT', 'BCMATH'); | |
} else { | |
die('GMP or bcmath required. (GMP is faster).'); | |
} | |
} | |
define('MAX_BASE', 256); // so we can use bcmath_Utils::bin2bc with "base256" | |
$secp256k1 = new CurveFp( | |
'115792089237316195423570985008687907853269984665640564039457584007908834671663', | |
'0', '7'); | |
$secp256k1_G = new Point($secp256k1, | |
'55066263022277343669578718895168534326250603453777594175500187360389116729240', | |
'32670510020758816978083085130507043184471273380659243275938904335757337482424', | |
'115792089237316195423570985008687907852837564279074904382605163141518161494337'); | |
/* The hash I want to sign. */ | |
$txHash = '9302bda273a887cb40c13e02a50b4071a31fd3aae3ae04021b0b843dd61ad18e'; | |
$txHash = gmp_Utils::gmp_hexdec($txHash); | |
/* Private key to sign the hash with. */ | |
$privKey = '18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725'; | |
$privKey = gmp_Utils::gmp_hexdec($privKey); | |
// Wikipedia (http://en.wikipedia.org/wiki/Elliptic_Curve_DSA#Signature_generation_algorithm) -- public key = private key * G, the base point | |
$pubKey = new PublicKey($secp256k1_G, Point::mul($privKey, $secp256k1_G)); | |
// check that the DER-encoded public key is what it's supposed to be -- not that this is necessarily correct DER encoding in general | |
assert(('04'.gmp_Utils::gmp_dechex($pubKey->getPoint()->getX()).gmp_Utils::gmp_dechex($pubKey->getPoint()->getY())) == '0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6'); | |
// the "secret multiplier" is just the private key value itself | |
$prvKey = new PrivateKey($pubKey, $privKey); | |
// I am not sure this is exactly the right range (could be off by 1 if inclusive), but this is what the ECC lib's test suite does so I assume it's correct. | |
// Unfortunately since this value is random and the StackExchange answer doesn't say what their k value was (it's generated by the OpenSSL lib they're using through Python), it's hard to verify exactly with the example | |
$k = gmp_Utils::gmp_random($secp256k1_G->getOrder()); | |
$signature = $prvKey->sign($txHash, $k); | |
// verify the signature | |
assert($pubKey->verifies($txHash, $signature)); | |
// verify with the DER-decoded signature given in the StackExchange answer -- if this also verifies it seems like a good sign we're on the right track (and it does, on my machine at least) | |
assert($pubKey->verifies($txHash, new Signature(gmp_Utils::gmp_hexdec('9e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a9567f75aa'), gmp_Utils::gmp_hexdec('bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7ebd7020cdc06')))); | |
/** | |
* The next steps involve DER/ASN.1 encoding, which I don't know much about, but here's some links I found: | |
* | |
* http://crypto.stackexchange.com/questions/1795/converting-a-der-ecdsa-signature-to-asn-1 | |
* http://stackoverflow.com/questions/6272020/do-any-php-libraries-exist-for-parsing-asn-1-or-generating-php-code-based-on-it | |
* https://github.com/FGrosse/PHPASN1 | |
* http://pumka.net/2009/12/19/reading-writing-and-converting-rsa-keys-in-pem-der-publickeyblob-and-privatekeyblob-formats/ | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment