<ol>
<li>Start with the public key bytes (a bytestring of length 64)</li>
<li>Of that public key, take the Keccak-256 hash used ubiquitously by Ethereum (make sure you get that right, as the ultimately standardized SHA3-256 hash differs). You should now have a bytestring of length 32.</li>
<li>Drop the first 12 bytes. You should now have a bytestring of length 20, the Ethereum address associated with your public key.</li>
</ol>

<p><strong>Update:</strong> Oops! I see you want it from the private key, not the public key. That's harder. You have to first derive the public key from the private key, which is best with the help of an EC crypto library. I can show you some example code in Scala, but the EC math is mostly a black box to me. First, interpret the 256 bit private key as an unsigned big integer. Then, see e.g. <a href="https://github.com/swaldman/consuela/blob/c373dd6c194ba8671de1d37245b5a34a575a583d/src/main/scala/com/mchange/sc/v1/consuela/crypto/package.scala#L294-L298" rel="nofollow noreferrer">here</a>. <code>Curve</code> represents the named eliptic curve <code>secp256k1</code>. The details of the math are, alas, beyond me, but hopefully in whatever environment you are coding you have access to a high quality crypto library.</p>

<p><strong>Update 2:</strong> In the comment thread, I speculated about where Ethereum's hash function diverged from the SHA3 standard. My speculation was mistaken, the version I thought was the incompatible change is the version Ethereum in fact uses. Thanks to work by <a href="https://www.kestrel.edu/home/people/mccarthy/" rel="nofollow noreferrer">Eric McCarthy</a>, who chased this down in great detail. Please see <a href="https://bitcoin.stackexchange.com/questions/42055/what-is-the-approach-to-calculate-an-ethereum-address-from-a-256-bit-private-key/42057#comment102225_42057">this comment below</a> for more details.</p>

CC BY-SA 3.0
2015-12-29T05:47:00.383Z
(sorry! my initial response misread the post as starting from the public key. i've added an update with imperfect hints on deriving the public from the private key.)
Steve Waldman
CC BY-SA 3.0
2015-12-29T22:52:05.050Z
I'm very confused, per [ETHEREUM: A SECURE DECENTRALISED GENERALISED TRANSACTION LEDGER](http://gavwood.com/paper.pdf) **I may format as typewriter text, e.g. the Keccak-256 hash function (as per the winning entry to the SHA-3 contest) is denoted KEC (and generally
referred to as plain Keccak).** FIPS202_SHA3_256 amounts to being Keccak(1088, 512, input, inputByteLen, 0x06, output, 32).  What are the Keccak parameters for Keccak-256?
skaht
CC BY-SA 3.0
2015-12-29T23:02:11.077Z
[Request for comment / opinions](https://forum.ethereum.org/discussion/5/request-for-comment-opinions) barely mentions sha3.
skaht
CC BY-SA 3.0
2015-12-29T23:37:07.050Z
[Per](http://vbuterin.com/ethereum.html) **Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key.**
skaht
CC BY-SA 3.0
2015-12-30T09:25:09.617Z
So, it's ugly. But the padding strategy of Keccak changed as the function was stewarded through the SHA3 standardization process. The relevant change I think happens at version 3.0 [here](https://github.com/gvanas/KeccakTools/commit/419b4259a96b097a7718cb11fc6a5a79893b8c30), see especially [padding.h](https://github.com/gvanas/KeccakTools/blob/419b4259a96b097a7718cb11fc6a5a79893b8c30/Sources/padding.h) and [padding.cpp](https://github.com/gvanas/KeccakTools/blob/419b4259a96b097a7718cb11fc6a5a79893b8c30/Sources/padding.cpp).
Steve Waldman
CC BY-SA 3.0
2015-12-30T09:29:02.377Z
Compare especially `OldDiversifiedKeccakPadding` and `MultiRatePadding`. Ethereum uses the old strategy. I think (but am not sure!) the diversifier param is set to its [default](http://keccak.noekeon.org/NoteOnKeccakParametersAndUsage.pdf) of 0. An easy way, in practice, to work this out is the compare the hash of the empty string. The ultimately standardized SHA3-256 hashes an empty string to `a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a`. The variant Ethereum uses hashes the same string to `c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470`.
Steve Waldman
CC BY-SA 3.0
2015-12-30T09:34:52.530Z
Google those two hashes and you'll find more discussion. For example, node's [js-sha3](https://www.npmjs.com/package/js-sha3) package can compute both variants, describing the ultimately standardized version as `sha3_256` and the old version as `keccak_256`. This is arguably a misnomer, as Keccak itself was updated, but the naming convention seems common. You'll have to find a library suitable to your purposes that makes available the appropriate, older, hash variant.
Steve Waldman
CC BY-SA 3.0
2015-12-31T04:52:19.783Z
Tested [KeccakTools](https://github.com/gvanas/KeccakTools) hacks to confirm that [un-commenting] (https://github.com/gvanas/KeccakTools/blob/419b4259a96b097a7718cb11fc6a5a79893b8c30/Sources/main.cpp#L324) and commenting out all of [genKATShortMsg.cpp](https://github.com/gvanas/KeccakTools/blob/master/Sources/genKATShortMsg.cpp#L36 and adding ```genShortMsg(1088,  512,  256, "keccak-256", true); // keccak-256, NOT FIPS202_SHA3_256``` will reproduce the hashes used to synthesize Ethereum addresses. **In short, ETH addresses are NOT CALCULATED using the NIST flavors of Keccak.**
skaht
CC BY-SA 3.0
2015-12-31T05:54:33.467Z
@ Steve Waldman, your instincts were right:-)
skaht
CC BY-SA 3.0
2015-12-31T06:00:41.227Z
@skaht not instinct! i banged my head against it just like you are. ;)
Steve Waldman
CC BY-SA 4.0
2019-07-24T13:53:14.953Z
I was mistaken about which version of Keccak is used by Eth 1.0. It is v3, not something earlier. [Eric McCarthy of Kestrel Institute](https://www.kestrel.edu/home/people/mccarthy/) has chased down and carefully verified precisely which version of Keccak Eth uses. It is [Version 3 from January 14, 2011](https://keccak.team/files/Keccak-submission-3.pdf). Thanks to McCarthy's work, the Ethereum Yellow Paper has been [updated](https://github.com/ethereum/yellowpaper/commit/aeeda84fcb5e4e751bb9fdb9241a6b39e13c254b) to reflect precisely which version of Keccak hash is used, an overdue improvement.
Steve Waldman
CC BY-SA 4.0
2015-12-29T05:24:21.977Z
2019-07-24T14:06:04.987Z
2019-07-24T14:06:04.987Z
Steve Waldman
<p>For computing ETH addresses, the last 20 bytes of a Keccak-256 hash are used. Must Not use the NIST FIPS 202 flavors of Keccak such as <a href="https://github.com/gvanas/KeccakCodePackage/blob/master/Standalone/CompactFIPS202/Keccak-readable-and-compact.c" rel="nofollow">KeccakCodePackage</a>. </p>

<p>However, a hack to main.c and genKATShortMsg.cpp from <a href="https://github.com/gvanas/KeccakTools" rel="nofollow">KeccakTools</a> will yield proper ETH addresses, detailed in a comment above. </p>

<p>For the following ETH private key: <code>b205a1e03ddf50247d8483435cd91f9c732bad281ad420061ab4310c33166276</code>. The associated public key results from using bx. </p>

<pre><code>% echo b205a1e03ddf50247d8483435cd91f9c732bad281ad420061ab4310c33166276 | bx ec-to-public -u
04**6cb84859e85b1d9a27e060fdede38bb818c93850fb6e42d9c7e4bd879f8b9153fd94ed48e1f63312dce58f4d778ff45a2e5abb08a39c1bc0241139f5e54de7df**
</code></pre>

<p>The following <code>KeccakTools/Example\ trails</code> configuration file is needed to to execute<br>
<code>../bin/KeccakTools</code> from the <code>Example\ trails</code> directory.</p>

<pre><code>% cat ShortMsgKAT.txt

\# Algorithm Name: NOT_FIPS202_SHA3_256
\# Principal Submitter: SKAHT
Len = 512
Msg = 6cb84859e85b1d9a27e060fdede38bb818c93850fb6e42d9c7e4bd879f8b9153fd94ed48e1f63312dce58f4d778ff45a2e5abb08a39c1bc0241139f5e54de7df
</code></pre>

<p>A file called <code>ShortMsgKAT_keccak-256.txt</code> is created from executing the <code>KeccakTools</code> that will contain:</p>

<pre><code>MD = 787EC5A5313A976F7BDF9EED**AFDEFC1937AE294C3BD55386A8B9775539D81653** 
</code></pre>

<p>when the hack documented above is performed to build <strong>KeccakTools</strong>.</p>

CC BY-SA 3.0
2016-06-24T00:31:02.893Z
The skinny for calculating Ethereum addresses is also found at this [location](http://bitcoin.stackexchange.com/questions/44260/can-ethereum-support-compressed-secp256k1-public-keys-to-compute-keccak-addresses).  Deduced that Ethereum does not natively support compressed private keys.
skaht
CC BY-SA 3.0
2015-12-31T05:35:05.767Z
2016-05-05T20:18:26.793Z
2016-05-05T20:18:26.793Z
skaht
<p>Answering the main headline question about 256-bit private keys, and header:  </p>

<blockquote>
  <p>"For a given private key generated by MyEtherWallet, I would like to
  see I have the tools to independently arrive at similar results."</p>
</blockquote>

<p>Firstly, it's important to check the private key size (whether generated randomly or deterministically) to make sure it is valid in terms of its use within curve secp256k1 curve (beyond the length in bits of the key), before generating the public key and address (although many applications such as the one below will check for you). </p>

<p><strong>Note</strong>: This applies to Bitcoin as well, not just ethereum, as they use the same curves, despite the address formatting being different due to the different steps and different hashing algorithms and encodings used (and although the same private key can be used across both, that is a different discussion).</p>

<p>While the curve itself is equal to the finite field <code>p</code> equal to: <code>((((((((2**256)-2**32)-2**9)-2**8)-2**7)-2**6)-2**4)-1)</code> and which in hexadecimal is: <code>'0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'</code> and 256 binary bits long,  the private key cannot be larger than the order <code>n</code> which is slighlty smaller even though it is also 256-bits: <code>'0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'</code></p>

<p>That is, <strong>the private key cannot be larger than <code>n</code></strong> as per the <a href="https://www.secg.org/sec2-v2.pdf" rel="nofollow noreferrer">secp256k1 curve parameters</a>. </p>

<p>After making that check to be sure the key is valid, the next steps would be to use something like the ECDSA library along with eth-keys library in Python.  </p>

<p>Here below is an example such program in Python that accepts a private key or can generate keys randomly (see comment in code after # for <code>private_key_hex=hex(int(bin(secrets.randbits(256)),base=2))</code>):</p>

<pre><code>import secrets
import math
import sha3
import ecdsa
from ecdsa import SigningKey, SECP256k1
from eth_keys import keys 

private_key_hex=hex(int(input('paste a 0x-padded 64 character hex string, total 66 with 0x'),base=16))
scep256k1_curvelimit= int(0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141) #Curve limit is 
if int(private_key_hex,base=16) &gt; scep256k1_curvelimit:
    print('private key is out of the range of the curve and invalid, do not use!')
else:
    print('private key is within range of curve')

#private_key_hex=hex(int(bin(secrets.randbits(256)),base=2)) Uncomment this to use RANDOM
private_key_hex_nopad=private_key_hex[2:]
private_key=bytearray.fromhex(private_key_hex_nopad)

def address_formatted(to_hash_str): 
    keccak = sha3.keccak_256()
    out = ''
    str_hash = to_hash_str.lower().replace('0x', '')
    keccak.update(str_hash.encode('ascii'))
    create_hash_digit = keccak.hexdigest()

    for i, c in enumerate(str_hash):
        if int(create_hash_digit[i], 16) &gt;= 8:
            out += c.upper()
        else:
            out += c
    return '0x' + out        

keccak = sha3.keccak_256()
f=private_key
private_key = ecdsa.SigningKey.from_string(f, curve=ecdsa.SECP256k1)
public_key = private_key.get_verifying_key().to_string()
keccak.update(public_key)
print(public_key)
address = keccak.hexdigest()[24:]
address_full = keccak.hexdigest()

print("Private key:", private_key.to_string().hex())
print("Public key: ", public_key.hex())
print("Ethereum Address, based on last 40 hex of Keccak Hash digest:    ", address_formatted(address))
print('Full Hash Digest (address is last 40 characters): ',address_full,)
</code></pre>

<p><strong>Note</strong>: the following code snippet from the above program is not necessary and I just added there for informational purposes, as the depended libraries have inherent checks to tell whether the private key (secret exponent) is less than <code>n</code> :</p>

<pre><code>scep256k1_curvelimit= int(0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141) #Curve limit is 
if int(private_key_hex,base=16) &gt; scep256k1_curvelimit:
    print('private key is out of the range of the curve and invalid, do not use!')
else:
    print('private key is within range of curve')
</code></pre>

<p>The output of the above program using the cryptographically-secure randomly-generated 256-bit key would look something like this (don't use these values on main net):</p>

<pre><code>b'\xa2%\xbfV_\xf4\xea\x03\x9b\xcc\xba&gt;&amp;En\x91\x0c\xd7NF\x16\xd6~\xe0\xa1f\xe2m\xa6\xe5\xe5Z\x08\xd0\xfa\x16Y\xb4\xb5G\xbaq9\xcaS\x1fb\x90{\x9c.r\xb8\x07\x12\xf1\xc8\x1e\xceC\xc3?K\x8b'
Private key: c2c72dfbff11dfb4e9d5b0a20c620c58b15bb7552753601f043db91331b0db15
Public key:  a225bf565ff4ea039bccba3e26456e910cd74e4616d67ee0a166e26da6e5e55a08d0fa1659b4b547ba7139ca531f62907b9c2e72b80712f1c81ece43c33f4b8b
Ethereum Address, based on last 40 hex of Keccak Hash digest:     0x6eA27154616a29708dce7650b475Dd6b82eBa6a3
Full Hash Digest (address is last 40 characters):  f616607efea8e1a5c2f0f8576ea27154616a29708dce7650b475dd6b82eba6a3
</code></pre>

<p><strong>Note</strong>: Keccak can also be accessed as part of the <a href="https://docs.python.org/3/library/hashlib.html" rel="nofollow noreferrer">Hashlib library</a> or installed from the <a href="https://pypi.org/project/pysha3/" rel="nofollow noreferrer">pysha3 library</a>, depending on the Python version installed.</p>

CC BY-SA 4.0
2019-08-21T13:29:16.007Z
2019-08-21T13:29:16.007Z
Steven Hatzakis
<p>For a given private key generated by <a href="https://www.myetherwallet.com/" rel="noreferrer">MyEtherWallet</a>, I would like to see I have the tools to independently arrive at similar results. </p>

<p>Wrote a wrapper around <a href="https://github.com/gvanas/KeccakCodePackage/blob/master/Standalone/CompactFIPS202/Keccak-readable-and-compact.c" rel="noreferrer">Keccak</a> to accept both hexadecimal and ASCII inputs to be sha3-224 or sha3-256 or  sha3-384 or sha3-512 hashed. Hashes are consistent with <a href="http://www.di-mgt.com.au/sha_testvectors.html" rel="noreferrer">Test Vectors</a>. Would like to apply it with bitcoin-explorer (<strong>bx</strong>) <strong>version3</strong> commands to see if I can synthesize ETH addresses. If successful at synthesizing addresses for ETH, XMR, and MAX altcoins, I go through the effort of submitting a pull request to add sha3 hashing capabilities to <strong>bx version3</strong>, and update this <a href="https://github.com/libbitcoin/libbitcoin/wiki/Altcoin-Version-Mappings" rel="noreferrer">Wiki</a> concerning the application of <strong>bx</strong> to altcoins.</p>

CC BY-SA 3.0
2015-12-30T03:38:44.817Z
To calculate a public address using bx's **secp256k1** capabilities is simply: ```% echo fc8fba997174132184998ab82b28e441e80c73236ccaf8b6a1efadc33febecfc | bx ec-to-public -u```
*04cf90dc2b34937fff7cf1eb4b260f1e5610231134b864761e508505938bbef8fc00aeb265797336b74146e018da7b78070f1f1072540a2c3fe83637ca5d605b3c*
skaht
CC BY-SA 3.0
2015-12-30T03:48:12.353Z
Issue I'm having is with Keccak sha3-256.  Dropping the *04* from the address above into a sha3-256 and taking the lower 20 bytes to the right isn't working.
skaht
CC BY-SA 3.0
2015-12-30T03:52:12.413Z
```% ./keccak -x -256 cf90dc2b34937fff7cf1eb4b260f1e5610231134b864761e508505938bbef8fc00aeb265797336b74146e018da7b78070f1f1072540a2c3fe83637ca5d605b3c``` b992c6ced76bf40cfe875feb**99d0dfbbb6eb831dc0605a82d084e5d930bc6631**
skaht
CC BY-SA 3.0
2016-05-26T07:14:38.013Z
How is it guaranteed that addresses are unique within the network then? What if I happen to have generated the same private key as someone else, then I will have the same address? Or, a more likely scenario, what if my private key is different to someone else, but it maps to the same address?
Graham P
CC BY-SA 3.0
2016-06-24T00:27:04.220Z
Q1) There is no guarantee that two different private keys can't have the same public ETH public address, just very improbable. Q2) If there is a collision between the private keys, s/he that spends first gets to reap booty at the loss of another. More likely to loose your funds at a bank for whatever reason...
skaht
<hash><ethereum>
What is the approach to calculate an Ethereum address from a 256 bit private key?
skaht
# What is the approach to calculate an Ethereum address from a 256 bit private key?

(Asked by: username_0 on 2015-12-29)

For a given private key generated by [MyEtherWallet](https://www.myetherwallet.com/), I would like to see I have the tools to independently arrive at similar results.

Wrote a wrapper around [Keccak](https://github.com/gvanas/KeccakCodePackage/blob/master/Standalone/CompactFIPS202/Keccak-readable-and-compact.c) to accept both hexadecimal and ASCII inputs to be sha3-224 or sha3-256 or sha3-384 or sha3-512 hashed. Hashes are consistent with [Test Vectors](http://www.di-mgt.com.au/sha_testvectors.html). Would like to apply it with bitcoin-explorer (**bx**) **version3** commands to see if I can synthesize ETH addresses. If successful at synthesizing addresses for ETH, XMR, and MAX altcoins, I go through the effort of submitting a pull request to add sha3 hashing capabilities to **bx version3**, and update this [Wiki](https://github.com/libbitcoin/libbitcoin/wiki/Altcoin-Version-Mappings) concerning the application of **bx** to altcoins.

**Tags:** hash, ethereum

> **Comments:**
> **username_0**: To calculate a public address using bx's **secp256k1** capabilities is simply: ```% echo fc8fba997174132184998ab82b28e441e80c73236ccaf8b6a1efadc33febecfc | bx ec-to-public -u``` *04cf90dc2b34937fff7cf1eb4b260f1e5610231134b864761e508505938bbef8fc00aeb265797336b74146e018da7b78070f1f1072540a2c3fe83637ca5d605b3c*  
> **username_0**: Issue I'm having is with Keccak sha3-256.  Dropping the *04* from the address above into a sha3-256 and taking the lower 20 bytes to the right isn't working.  
> **username_0**: ```% ./keccak -x -256 cf90dc2b34937fff7cf1eb4b260f1e5610231134b864761e508505938bbef8fc00aeb265797336b74146e018da7b78070f1f1072540a2c3fe83637ca5d605b3c``` b992c6ced76bf40cfe875feb**99d0dfbbb6eb831dc0605a82d084e5d930bc6631**  
> **username_1**: How is it guaranteed that addresses are unique within the network then? What if I happen to have generated the same private key as someone else, then I will have the same address? Or, a more likely scenario, what if my private key is different to someone else, but it maps to the same address?  
> **username_0**: Q1) There is no guarantee that two different private keys can't have the same public ETH public address, just very improbable. Q2) If there is a collision between the private keys, s/he that spends first gets to reap booty at the loss of another. More likely to loose your funds at a bank for whatever reason...  

---

## 3 answers

### Answer by username_2 on 2015-12-29. Score: 6

1. Start with the public key bytes (a bytestring of length 64)
2. Of that public key, take the Keccak-256 hash used ubiquitously by Ethereum (make sure you get that right, as the ultimately standardized SHA3-256 hash differs). You should now have a bytestring of length 32.
3. Drop the first 12 bytes. You should now have a bytestring of length 20, the Ethereum address associated with your public key.

**Update:** Oops! I see you want it from the private key, not the public key. That's harder. You have to first derive the public key from the private key, which is best with the help of an EC crypto library. I can show you some example code in Scala, but the EC math is mostly a black box to me. First, interpret the 256 bit private key as an unsigned big integer. Then, see e.g. [here](https://github.com/swaldman/consuela/blob/c373dd6c194ba8671de1d37245b5a34a575a583d/src/main/scala/com/mchange/sc/v1/consuela/crypto/package.scala#L294-L298). `Curve` represents the named eliptic curve `secp256k1`. The details of the math are, alas, beyond me, but hopefully in whatever environment you are coding you have access to a high quality crypto library.

**Update 2:** In the comment thread, I speculated about where Ethereum's hash function diverged from the SHA3 standard. My speculation was mistaken, the version I thought was the incompatible change is the version Ethereum in fact uses. Thanks to work by [Eric McCarthy](https://www.kestrel.edu/home/people/mccarthy/), who chased this down in great detail. Please see [this comment below](https://bitcoin.stackexchange.com/questions/42055/what-is-the-approach-to-calculate-an-ethereum-address-from-a-256-bit-private-key/42057#comment102225_42057) for more details.

> **Comments:**
> **username_2**: (sorry! my initial response misread the post as starting from the public key. i've added an update with imperfect hints on deriving the public from the private key.)  
> **username_0**: I'm very confused, per [ETHEREUM: A SECURE DECENTRALISED GENERALISED TRANSACTION LEDGER](http://gavwood.com/paper.pdf) **I may format as typewriter text, e.g. the Keccak-256 hash function (as per the winning entry to the SHA-3 contest) is denoted KEC (and generally referred to as plain Keccak).** FIPS202_SHA3_256 amounts to being Keccak(1088, 512, input, inputByteLen, 0x06, output, 32).  What are the Keccak parameters for Keccak-256?  
> **username_0**: [Request for comment / opinions](https://forum.ethereum.org/discussion/5/request-for-comment-opinions) barely mentions sha3.  
> **username_0**: [Per](http://vbuterin.com/ethereum.html) **Instead of addresses being the RIPEMD160 hash of the SHA256 hash of the public key prefixed with 04, addresses are simply the last 20 bytes of the SHA3 hash of the public key.**  
> **username_2**: So, it's ugly. But the padding strategy of Keccak changed as the function was stewarded through the SHA3 standardization process. The relevant change I think happens at version 3.0 [here](https://github.com/gvanas/KeccakTools/commit/419b4259a96b097a7718cb11fc6a5a79893b8c30), see especially [padding.h](https://github.com/gvanas/KeccakTools/blob/419b4259a96b097a7718cb11fc6a5a79893b8c30/Sources/padding.h) and [padding.cpp](https://github.com/gvanas/KeccakTools/blob/419b4259a96b097a7718cb11fc6a5a79893b8c30/Sources/padding.cpp).  
> **username_2**: Compare especially `OldDiversifiedKeccakPadding` and `MultiRatePadding`. Ethereum uses the old strategy. I think (but am not sure!) the diversifier param is set to its [default](http://keccak.noekeon.org/NoteOnKeccakParametersAndUsage.pdf) of 0. An easy way, in practice, to work this out is the compare the hash of the empty string. The ultimately standardized SHA3-256 hashes an empty string to `a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a`. The variant Ethereum uses hashes the same string to `c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470`.  
> **username_2**: Google those two hashes and you'll find more discussion. For example, node's [js-sha3](https://www.npmjs.com/package/js-sha3) package can compute both variants, describing the ultimately standardized version as `sha3_256` and the old version as `keccak_256`. This is arguably a misnomer, as Keccak itself was updated, but the naming convention seems common. You'll have to find a library suitable to your purposes that makes available the appropriate, older, hash variant.  
> **username_0**: Tested [KeccakTools](https://github.com/gvanas/KeccakTools) hacks to confirm that [un-commenting] (https://github.com/gvanas/KeccakTools/blob/419b4259a96b097a7718cb11fc6a5a79893b8c30/Sources/main.cpp#L324) and commenting out all of [genKATShortMsg.cpp](https://github.com/gvanas/KeccakTools/blob/master/Sources/genKATShortMsg.cpp#L36 and adding ```genShortMsg(1088,  512,  256, "keccak-256", true); // keccak-256, NOT FIPS202_SHA3_256``` will reproduce the hashes used to synthesize Ethereum addresses. **In short, ETH addresses are NOT CALCULATED using the NIST flavors of Keccak.**  
> **username_0**: @ username_2 username_2, your instincts were right:-)  
> **username_2**: @username_0 not instinct! i banged my head against it just like you are. ;)  
> **username_2**: I was mistaken about which version of Keccak is used by Eth 1.0. It is v3, not something earlier. [Eric McCarthy of Kestrel Institute](https://www.kestrel.edu/home/people/mccarthy/) has chased down and carefully verified precisely which version of Keccak Eth uses. It is [Version 3 from January 14, 2011](https://keccak.team/files/Keccak-submission-3.pdf). Thanks to McCarthy's work, the Ethereum Yellow Paper has been [updated](https://github.com/ethereum/yellowpaper/commit/aeeda84fcb5e4e751bb9fdb9241a6b39e13c254b) to reflect precisely which version of Keccak hash is used, an overdue improvement.  

---

### Answer by username_0 on 2015-12-31. Score: 2

For computing ETH addresses, the last 20 bytes of a Keccak-256 hash are used. Must Not use the NIST FIPS 202 flavors of Keccak such as [KeccakCodePackage](https://github.com/gvanas/KeccakCodePackage/blob/master/Standalone/CompactFIPS202/Keccak-readable-and-compact.c).

However, a hack to main.c and genKATShortMsg.cpp from [KeccakTools](https://github.com/gvanas/KeccakTools) will yield proper ETH addresses, detailed in a comment above.

For the following ETH private key: `b205a1e03ddf50247d8483435cd91f9c732bad281ad420061ab4310c33166276`. The associated public key results from using bx.

```
% echo b205a1e03ddf50247d8483435cd91f9c732bad281ad420061ab4310c33166276 | bx ec-to-public -u
04**6cb84859e85b1d9a27e060fdede38bb818c93850fb6e42d9c7e4bd879f8b9153fd94ed48e1f63312dce58f4d778ff45a2e5abb08a39c1bc0241139f5e54de7df**

```

The following `KeccakTools/Example\ trails` configuration file is needed to to execute  
`../bin/KeccakTools` from the `Example\ trails` directory.

```
% cat ShortMsgKAT.txt

\# Algorithm Name: NOT_FIPS202_SHA3_256
\# Principal Submitter: username_0
Len = 512
Msg = 6cb84859e85b1d9a27e060fdede38bb818c93850fb6e42d9c7e4bd879f8b9153fd94ed48e1f63312dce58f4d778ff45a2e5abb08a39c1bc0241139f5e54de7df

```

A file called `ShortMsgKAT_keccak-256.txt` is created from executing the `KeccakTools` that will contain:

```
MD = 787EC5A5313A976F7BDF9EED**AFDEFC1937AE294C3BD55386A8B9775539D81653** 

```

when the hack documented above is performed to build **KeccakTools**.

> **Comments:**
> **username_0**: The skinny for calculating Ethereum addresses is also found at this [location](http://bitcoin.stackexchange.com/questions/44260/can-ethereum-support-compressed-secp256k1-public-keys-to-compute-keccak-addresses).  Deduced that Ethereum does not natively support compressed private keys.  

---

### Answer by username_3 on 2019-08-21. Score: 0

Answering the main headline question about 256-bit private keys, and header:

> "For a given private key generated by MyEtherWallet, I would like to
> see I have the tools to independently arrive at similar results."

Firstly, it's important to check the private key size (whether generated randomly or deterministically) to make sure it is valid in terms of its use within curve secp256k1 curve (beyond the length in bits of the key), before generating the public key and address (although many applications such as the one below will check for you).

**Note**: This applies to Bitcoin as well, not just ethereum, as they use the same curves, despite the address formatting being different due to the different steps and different hashing algorithms and encodings used (and although the same private key can be used across both, that is a different discussion).

While the curve itself is equal to the finite field `p` equal to: `((((((((2**256)-2**32)-2**9)-2**8)-2**7)-2**6)-2**4)-1)` and which in hexadecimal is: `'0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'` and 256 binary bits long, the private key cannot be larger than the order `n` which is slighlty smaller even though it is also 256-bits: `'0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'`

That is, **the private key cannot be larger than `n`** as per the [secp256k1 curve parameters](https://www.secg.org/sec2-v2.pdf).

After making that check to be sure the key is valid, the next steps would be to use something like the ECDSA library along with eth-keys library in Python.

Here below is an example such program in Python that accepts a private key or can generate keys randomly (see comment in code after # for `private_key_hex=hex(int(bin(secrets.randbits(256)),base=2))`):

```
import secrets
import math
import sha3
import ecdsa
from ecdsa import SigningKey, SECP256k1
from eth_keys import keys 

private_key_hex=hex(int(input('paste a 0x-padded 64 character hex string, total 66 with 0x'),base=16))
scep256k1_curvelimit= int(0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141) #Curve limit is 
if int(private_key_hex,base=16) > scep256k1_curvelimit:
    print('private key is out of the range of the curve and invalid, do not use!')
else:
    print('private key is within range of curve')

#private_key_hex=hex(int(bin(secrets.randbits(256)),base=2)) Uncomment this to use RANDOM
private_key_hex_nopad=private_key_hex[2:]
private_key=bytearray.fromhex(private_key_hex_nopad)

def address_formatted(to_hash_str): 
    keccak = sha3.keccak_256()
    out = ''
    str_hash = to_hash_str.lower().replace('0x', '')
    keccak.update(str_hash.encode('ascii'))
    create_hash_digit = keccak.hexdigest()

    for i, c in enumerate(str_hash):
        if int(create_hash_digit[i], 16) >= 8:
            out += c.upper()
        else:
            out += c
    return '0x' + out        

keccak = sha3.keccak_256()
f=private_key
private_key = ecdsa.SigningKey.from_string(f, curve=ecdsa.SECP256k1)
public_key = private_key.get_verifying_key().to_string()
keccak.update(public_key)
print(public_key)
address = keccak.hexdigest()[24:]
address_full = keccak.hexdigest()

print("Private key:", private_key.to_string().hex())
print("Public key: ", public_key.hex())
print("Ethereum Address, based on last 40 hex of Keccak Hash digest:    ", address_formatted(address))
print('Full Hash Digest (address is last 40 characters): ',address_full,)

```

**Note**: the following code snippet from the above program is not necessary and I just added there for informational purposes, as the depended libraries have inherent checks to tell whether the private key (secret exponent) is less than `n` :

```
scep256k1_curvelimit= int(0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141) #Curve limit is 
if int(private_key_hex,base=16) > scep256k1_curvelimit:
    print('private key is out of the range of the curve and invalid, do not use!')
else:
    print('private key is within range of curve')

```

The output of the above program using the cryptographically-secure randomly-generated 256-bit key would look something like this (don't use these values on main net):

```
b'\xa2%\xbfV_\xf4\xea\x03\x9b\xcc\xba>&En\x91\x0c\xd7NF\x16\xd6~\xe0\xa1f\xe2m\xa6\xe5\xe5Z\x08\xd0\xfa\x16Y\xb4\xb5G\xbaq9\xcaS\x1fb\x90{\x9c.r\xb8\x07\x12\xf1\xc8\x1e\xceC\xc3?K\x8b'
Private key: c2c72dfbff11dfb4e9d5b0a20c620c58b15bb7552753601f043db91331b0db15
Public key:  a225bf565ff4ea039bccba3e26456e910cd74e4616d67ee0a166e26da6e5e55a08d0fa1659b4b547ba7139ca531f62907b9c2e72b80712f1c81ece43c33f4b8b
Ethereum Address, based on last 40 hex of Keccak Hash digest:     0x6eA27154616a29708dce7650b475Dd6b82eBa6a3
Full Hash Digest (address is last 40 characters):  f616607efea8e1a5c2f0f8576ea27154616a29708dce7650b475dd6b82eba6a3

```

**Note**: Keccak can also be accessed as part of the [Hashlib library](https://docs.python.org/3/library/hashlib.html) or installed from the [pysha3 library](https://pypi.org/project/pysha3/), depending on the Python version installed.


---

