simplito / elliptic-php

Fast, general Elliptic Curve Cryptography library. Supports curves used in Bitcoin, Ethereum and other cryptocurrencies (secp256k1, ed25519, ..)
MIT License
220 stars 52 forks source link

problem in making ethereum wallet address with your library #6

Closed se8820726 closed 6 years ago

se8820726 commented 6 years ago

hi I'm using your library to generate private key and then public key and then generate ethereum wallet address from it. this is my code:

use Elliptic\EC;
use kornrunner\Keccak;

$ec = new EC('secp256k1');
$key = $ec->genKeyPair();

$priv = $key->getPrivate('hex');
$pub = substr($key->getPublic('hex'),2);

$hash = Keccak::hash($pub, 256);
$wallet = substr($hash,-40);

var_dump($priv);    // ex:  77a1d1930a78c7ff16a849b519729b67e738ea49c4db19ee8a6f1dea816c7577
var_dump($pub);   // ex:   db93fb7c12b067e2e7794bb49c704159d78a0c4efa5f7e65c5bbb8e343ec602d5ee39169e3a06d4cb0db764445f2772ed5fdb1d3fd18a2f5cdc15b2581b74216
var_dump($hash);  // ex: 5335602cd85aff99e78fdb15cee40b78e358cfb8c4f1a8f1110424401e3febc6
var_dump($wallet);// ex: cee40b78e358cfb8c4f1a8f1110424401e3febc6

but when I use this private key in https://www.myetherwallet.com/ it shows below address as wallet: B1b71CEc4a07F4EDAc54A620f4Cf4EbC6e7405DD

would you help me to find solution please?

slacker69 commented 6 years ago

I'm not the owner of this library but I started work on how to convert ECC keys into DER/PEM format, maybe that would work. here is some partially finished code to try out:

//for the secp256k1 curve you can do this: $der_private = "\x30\x74\x02\x01\x01\x04\x20".$priv->toString(32 bytes)."\xa0\x07\x06\x05\x2b\x81\x04\x00\x0a\xa1\x44\x03\x42\x00\x04".$pub->x->toString(32 bytes).$pub->y->toString(32 bytes); $pem_private = implode(PHP_EOL, str_split(base64_encode($der_private), 64)); $pem_private = '-----BEGIN EC PRIVATE KEY-----'.PHP_EOL.$pem_private; $pem_private .= '-----END EC PRIVATE KEY-----'.PHP_EOL;

$der_public = "\x30\x56\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04\x00\x0a\x03\x42\x00\x04".$pub->x->toString(32 bytes).$pub->y->toString(32 bytes); $pem_public = implode(PHP_EOL, str_split(base64_encode($der_public), 64)); $pem_public = '-----BEGIN PUBLIC KEY-----'.PHP_EOL.$pem_public; $pem_public .= '-----END PUBLIC KEY-----'.PHP_EOL;

ssmyczynski commented 6 years ago

Here is working example:

use Elliptic\EC;
use kornrunner\Keccak;

function pubKeyToAddress($pubkey) {
        return "0x" . substr(Keccak::hash(substr(hex2bin($pubkey->encode("hex")), 1), 256), 24);
}

$ec = new EC('secp256k1');
$priv = $ec->genKeyPair();
$pub  = $priv->getPublic();

echo 'Private: ' . $priv->getPrivate("hex") . PHP_EOL;
echo 'Public:  ' . $pub->encode("hex", true) . PHP_EOL;
echo 'Address: ' . pubKeyToAddress($pub) . PHP_EOL;