An Ethereum and blockchain bloghttps://kobl.one/index.xml
Recent content on An Ethereum and blockchain blogHugo -- gohugo.ioen-usWed, 22 Feb 2017 10:01:47 +0100About this bloghttps://kobl.one/about/
Wed, 22 Feb 2017 10:01:47 +0100https://kobl.one/about/
<p>Hi to you! My name is Vincent Kobel, I&rsquo;m a developer &amp; security engineer currently working in Switzerland. Most of my passion right now is focused towards blockchain technologies and peer-to-peer networks like:</p>
<p><a href="https://www.ethereum.org/">Ethereum</a>, a decentralized platform and cryptocurrency like Bitcoin allowing &ldquo;smart contracts&rdquo; to run on the blockchain. Think of them as small programs where their execution is validated by all the nodes composing the network.</p>
<p><a href="http://counterparty.io/">Counterparty</a>, implements the same functionality as Ethereum on top of the Bitcoin network.</p>
<p><a href="https://ipfs.io/">IPFS</a>, a peer-to-peer network created to form a distributed file system, based on content itself rather than a location, a hash instead of a URL.</p>
<p>If you were wondering about this blog&rsquo;s name <strong>&ldquo;Unfolding Protons&rdquo;</strong>, it&rsquo;s a reference to the awesome sci-fi novel <a href="http://www.goodreads.com/book/show/20518872-the-three-body-problem">The Three-Body Problem</a> by Chinese author Liu Cixin.</p>
<h2 id="friend-s-blogs">Friend&rsquo;s blogs ♥</h2>
<ul>
<li>The mighty <a href="https://tome.one/">Tome One</a></li>
</ul>
Create full Ethereum wallet, keypair and addresshttps://kobl.one/blog/create-full-ethereum-keypair-and-address/
Wed, 15 Feb 2017 13:36:41 +0100https://kobl.one/blog/create-full-ethereum-keypair-and-address/
<h1 id="generating-a-usable-ethereum-wallet-and-its-corresponding-keys">Generating a usable Ethereum wallet and its corresponding keys</h1>
<h3 id="contents">Contents</h3>
<ul>
<li><a href="#generating-the-ec-private-key">Generating the EC private key</a></li>
<li><a href="#derive-the-ethereum-address-from-the-public-key">Derive the Ethereum address from the public key</a></li>
<li><a href="#importing-the-private-key-to-geth">Importing the private key to geth</a></li>
<li><a href="#complete-example">Complete example</a></li>
</ul>
<p>This article is a guide on how to generate an ECDSA private key and derive its Ethereum address. Using OpenSSL and keccak-256sum from a terminal.</p>
<p>You can find a working implementation of keccak-256sum <a href="https://github.com/maandree/sha3sum">here</a>. Cool thing, it exists as a package in the <a href="https://aur.archlinux.org/packages/sha3sum/">Arch User Repository as well</a>. If you&rsquo;re feeling lazy, you can find statically linked pre-compiled versions for <a href="https://github.com/vkobel/ethereum-generate-wallet/tree/master/lib">both i386 and x86-64 on my repo</a>.</p>
<p><strong>Warning SHA3 != keccak</strong>. Ethereum is using the keccak-256 algorithm and not the standard sha3. More info at <a href="http://ethereum.stackexchange.com/questions/550/which-cryptographic-hash-function-does-ethereum-use">Stackoverflow</a>.</p>
<p>I have a <a href="https://github.com/vkobel/ethereum-generate-wallet">repository</a> with complete scripts in both bash and python if you&rsquo;d like.</p>
<h2 id="generating-the-ec-private-key">Generating the EC private key</h2>
<p>First of all we use OpenSSL ecparam command to generate an elliptic curve private key. Ethereum standard is to use the secp256k1 curve. The same curve is used by Bitcoin.</p>
<p>This command will print the private key in PEM format (using the wonderful ASN.1 key structure) on stdout. If you want more OpenSSL info on elliptic curves, please feel free to <a href="https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations">dig further</a>.</p>
<pre><code class="language-bash">&gt; openssl ecparam -name secp256k1 -genkey -noout
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIFDLYO9KuwsC4ej2UsdA4SYk7s3lb8aZuW+B8rjugrMmoAcGBSuBBAAK
oUQDQgAEsNjwhFoLKLXGBxfpMv3ILhzg2FeySRlFhtjfi3s8YFZzJtmckVR3N/YL
JLnUV7w3orZUyAz77k0ebug0ILd1lQ==
-----END EC PRIVATE KEY-----
</code></pre>
<p>On its own this command is not very useful for us, but if you pipe it with the ec command it will display both private and public part in hexadecimal format, and this is what we want! Let&rsquo;s do it:</p>
<pre><code class="language-bash">&gt; openssl ecparam -name secp256k1 -genkey -noout | openssl ec -text -noout
read EC key
Private-Key: (256 bit)
priv:
20:80:65:a2:47:ed:be:5d:f4:d8:6f:bd:c0:17:13:
03:f2:3a:76:96:1b:e9:f6:01:38:50:dd:2b:dc:75:
9b:bb
pub:
04:83:6b:35:a0:26:74:3e:82:3a:90:a0:ee:3b:91:
bf:61:5c:6a:75:7e:2b:60:b9:e1:dc:18:26:fd:0d:
d1:61:06:f7:bc:1e:81:79:f6:65:01:5f:43:c6:c8:
1f:39:06:2f:c2:08:6e:d8:49:62:5c:06:e0:46:97:
69:8b:21:85:5e
ASN1 OID: secp256k1
</code></pre>
<p>This command decodes the ASN.1 structure and derives the public key from the private one. Sometimes, OpenSSL is adding a null byte (0x00) in front of the private part, I don&rsquo;t know why it does that but you have to trim any leading zero bytes in order to use it with Ethereum.</p>
<p>The private key <strong>must be 32 bytes and not begin with 0x00</strong> and the public one <strong>must be uncompressed and 64 bytes long</strong> or 65 with the constant 0x04 prefix. More on that in the next section.</p>
<h2 id="derive-the-ethereum-address-from-the-public-key">Derive the Ethereum address from the public key</h2>
<p>The public key is what we need in order to derive its Ethereum address. Every EC public key begins with the 0x04 prefix before giving the location of the two point on the curve. You should remove this leading 0x04 byte in order to hash it correctly. I recommend the excellent <a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/">Cloudflare article on elliptic curves</a> if you want more details.</p>
<p>Use any method you like to get it in the form of an hexadecimal string (without line return nor semicolon). Here is an example of extraction using <em>grep</em>, <em>tail</em>, <em>tr</em> and <em>sed</em>. I&rsquo;m sure there&rsquo;s an easier way to do it but I&rsquo;m not a bash guru. You can find the scripts (python as well) on <a href="https://github.com/vkobel/ethereum-generate-wallet">my github repository</a>.</p>
<p><strong>The examples below assume you saved the output of the openssl commands in a file named &lsquo;Key&rsquo;</strong></p>
<pre><code class="language-bash"># Extract the public key and remove the EC prefix 0x04
&gt; cat Key | grep pub -A 5 | tail -n +2 |
tr -d '\n[:space:]:' | sed 's/^04//' &gt; pub
836b35a026743e823a90a0ee3b91bf615c6a757e2b60b9e1dc1826fd0dd16106f7bc1e8179f665015f43c6c81f39062fc2086ed849625c06e04697698b21855e
</code></pre>
<p>The pub file now contains the hexadecimal value of the public key without the 0x04 prefix.</p>
<p>An Ethereum address is made of 20 bytes (40 hex characters long), it is commonly represented by adding the 0x prefix. In order to derive it, one should take the keccak-256 hash of the hexadecimal form of a public key, then keep only the last 20 bytes (aka get rid of the first 12 bytes).</p>
<p>Simply pass the file containing the public key in hexadecimal format to the keccak-256sum command. <strong>Do not forget to use the &lsquo;-x&rsquo; option</strong> in order to interpret it as hexadecimal and not a simple string.</p>
<p>In the below snippet, the &lsquo;-l&rsquo; option is to output as lowercase. Then I use <em>tr</em> to delete the trailing &lsquo; -&rsquo; from the stdout of the keccak command. Finally, I take only the last 40 characters using the <em>tail</em> command. Yes, I specify 41 in order to get 40 characters, probably because of a line return.</p>
<pre><code class="language-bash"># Generate the hash and take the address part
&gt; cat pub | keccak-256sum -x -l | tr -d ' -' | tail -c 41
0bed7abd61247635c1973eb38474a2516ed1d884
</code></pre>
<p>Which gives us the Ethereum address <code>0x0bed7abd61247635c1973eb38474a2516ed1d884</code></p>
<p><strong>CAUTION!</strong> if your final address looks like <code>*0xdcc703c0E500B653Ca82273B7BFAd8045D85a470*</code> this means you have hashed an empty public key. Sending funds to this address will lock them forever! People made this mistake before as shown on <a href="https://etherscan.io/address/0xdcc703c0E500B653Ca82273B7BFAd8045D85a470">etherscan</a>.</p>
<p><em>Thanks to Linus Miller for highlighting this issue in the comments section below.</em></p>
<h2 id="importing-the-private-key-to-geth">Importing the private key to geth</h2>
<p>Let&rsquo;s import the private key to geth and therefore validating the derivation of the address.</p>
<p>To begin with, we format the private key the same way we did for the public one above. The only exception is removing the leading 0x00 instead of the 0x04:</p>
<pre><code class="language-bash"># Extract the private key and remove the leading zero byte
&gt; cat Key | grep priv -A 3 | tail -n +2 |
tr -d '\n[:space:]:' | sed 's/^00//' &gt; priv
208065a247edbe5df4d86fbdc0171303f23a76961be9f6013850dd2bdc759bbb
</code></pre>
<p>To import it to geth, use the <code>account import</code> feature like this:</p>
<pre><code class="language-bash">&gt; geth account import priv
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {0bed7abd61247635c1973eb38474a2516ed1d884}
</code></pre>
<p><strong>YAY!</strong> the address returned by geth is the same we computed. Note that geth will ask you a passphrase to encrypt your private key.</p>
<p>You&rsquo;re now ready to use the new account with geth. Of course, it would be easier to take advantage of the <code>geth account new</code> feature in order to quickly setup an Ethereum account. But manually doing it gives you the power of knowing your public and unencrypted private keys. In addition, this would be useful to generate a secure Ethereum account completely off chain.</p>
<h2 id="complete-example">Complete example</h2>
<pre><code class="language-bash"># Generate the private and public keys
&gt; openssl ecparam -name secp256k1 -genkey -noout |
openssl ec -text -noout &gt; Key
# Extract the public key and remove the EC prefix 0x04
&gt; cat Key | grep pub -A 5 | tail -n +2 |
tr -d '\n[:space:]:' | sed 's/^04//' &gt; pub
# Extract the private key and remove the leading zero byte
&gt; cat Key | grep priv -A 3 | tail -n +2 |
tr -d '\n[:space:]:' | sed 's/^00//' &gt; priv
# Generate the hash and take the address part
&gt; cat pub | keccak-256sum -x -l | tr -d ' -' | tail -c 41 &gt; address
# (Optional) import the private key to geth
&gt; geth account import priv
</code></pre>