<p>Yes, it will generate a random ECDSA private key in hexadecimal ASCII form. You don't really need to specifically check whether the key is greater than the maximum -- pretty much every implementation that will take an ECDSA key in hexadecimal ASCII knows how to handle a key above the maximum sanely. (By subtracting the max value from the key and then using that.)</p>

CC BY-SA 3.0
2013-10-22T20:33:03.347Z
2013-10-22T20:33:03.347Z
David Schwartz
<p>This is not entirely responsive to your question, but in furtherance of David Schwartz's response (which was, in summary, "yes"), I don't think you need to recreate an instance SystemRandom for each hex character you generate. From <a href="https://docs.python.org/2/library/random.html#random.SystemRandom" rel="nofollow">https://docs.python.org/2/library/random.html#random.SystemRandom</a>:</p>

<blockquote>
  <p>[SystemRandom] uses the os.urandom() function for generating random numbers from sources provided by the operating system. Not available on all systems. Does not rely on software state and sequences are not reproducible. Accordingly, the seed() and jumpahead() methods have no effect and are ignored. The getstate() and setstate() methods raise NotImplementedError if called.</p>
</blockquote>

<p>I think you can call SystemRandom.randint on your bounds directly (with a pretty big speed boost):</p>

<pre><code>from random import SystemRandom
from binascii import hexlify
from struct import Struct

SYS_RAN = SystemRandom()
PACKER = Struct('&gt;QQQQ')
MIN_VAL = 0x1L
MAX_VAL = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

def mkprivkey():
    key = SYS_RAN.randint(MIN_VAL, MAX_VAL)
    key0 = key &gt;&gt; 192
    key1 = (key &gt;&gt; 128) &amp; 0xffffffffffffffff
    key2 = (key &gt;&gt; 64) &amp; 0xffffffffffffffff
    key3 = key &amp; 0xffffffffffffffff

    return hexlify(PACKER.pack(key0, key1, key2, key3))
</code></pre>

<p>In my <a href="https://gist.github.com/mbogosian/8488da5bda5d75651e25" rel="nofollow">testing</a>, the above is about an order of magnitude faster, even after normalizing your creation of SystemRandom instances and removing your test to see if you've exceeded the max value (per David Schwartz's suggestion):</p>

<pre><code>% time python ./test_ecdsaprivkey.py
mkprivkey:          0.016 ms avg
create_private_key: 0.168 ms avg
python ./test_ecdsaprivkey.py  9.99s user 11.00s system 86% cpu 24.388 total
</code></pre>

<p>Of course, this probably doesn't matter unless you're creating tens of thousands of keys.</p>

CC BY-SA 3.0
2014-05-25T16:33:42.350Z
2014-05-26T02:30:16.083Z
2014-05-26T02:30:16.083Z
posita
<p><code>import os
import binascii
private_key = binascii.hexlify(os.urandom(32)).decode()
print("private key = " + private_key)</code></p>

CC BY-SA 3.0
2018-01-16T09:09:14.683Z
Welcome to Bitcoin.SE! Whilst this may theoretically answer the question, [it would be preferable](//meta.stackoverflow.com/q/8259) to include some explanation of your code too so that people can understand how it works and what it does
meshcollider
CC BY-SA 3.0
2018-01-16T06:46:35.407Z
2018-01-16T06:46:35.407Z
satoshighost
<p>Would this Python code generate a valid ECDSA private key?</p>

<pre><code>import random

def r(a, b):
    sys_ran = random.SystemRandom()
    return sys_ran.randint(a, b)

def create_private_key():
    hex_chars = '0123456789ABCDEF'
    ran_hex = '';

    for i in range(64):
        ran_hex += hex_chars[r(0, 15)]

    max_hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'

    if int(ran_hex, 16) &lt;= int(max_hex, 16):
        return ran_hex
    else:
        return create_private_key()

private_key = create_private_key()
print('Private key: ' + private_key)
</code></pre>

<p>As far as I can tell from the <a href="https://en.bitcoin.it/wiki/" rel="nofollow">Bitcoin wiki</a>, an ECDSA private key is any 64 character hexadecimal (or the corresponding decimal) number between 0x1 and 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141. It doesn't mention anything about any special algorithms required for the private key to be valid.</p>

<private-key>
Python code to generate private ECDSA key
zombio
# Python code to generate private ECDSA key

(Asked by: username_0 on 2013-10-22)

Would this Python code generate a valid ECDSA private key?

```
import random

def r(a, b):
    sys_ran = random.SystemRandom()
    return sys_ran.randint(a, b)

def create_private_key():
    hex_chars = '0123456789ABCDEF'
    ran_hex = '';

    for i in range(64):
        ran_hex += hex_chars[r(0, 15)]

    max_hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'

    if int(ran_hex, 16) <= int(max_hex, 16):
        return ran_hex
    else:
        return create_private_key()

private_key = create_private_key()
print('Private key: ' + private_key)

```

As far as I can tell from the [Bitcoin wiki](https://en.bitcoin.it/wiki/), an ECDSA private key is any 64 character hexadecimal (or the corresponding decimal) number between 0x1 and 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141. It doesn't mention anything about any special algorithms required for the private key to be valid.

**Tags:** private-key


---

## 3 answers

### Answer by username_1 on 2013-10-22. Score: 4

Yes, it will generate a random ECDSA private key in hexadecimal ASCII form. You don't really need to specifically check whether the key is greater than the maximum -- pretty much every implementation that will take an ECDSA key in hexadecimal ASCII knows how to handle a key above the maximum sanely. (By subtracting the max value from the key and then using that.)


---

### Answer by username_2 on 2014-05-25. Score: 2

This is not entirely responsive to your question, but in furtherance of username_1 username_1's response (which was, in summary, "yes"), I don't think you need to recreate an instance SystemRandom for each hex character you generate. From <https://docs.python.org/2/library/random.html#random.SystemRandom>:

> [SystemRandom] uses the os.urandom() function for generating random numbers from sources provided by the operating system. Not available on all systems. Does not rely on software state and sequences are not reproducible. Accordingly, the seed() and jumpahead() methods have no effect and are ignored. The getstate() and setstate() methods raise NotImplementedError if called.

I think you can call SystemRandom.randint on your bounds directly (with a pretty big speed boost):

```
from random import SystemRandom
from binascii import hexlify
from struct import Struct

SYS_RAN = SystemRandom()
PACKER = Struct('>QQQQ')
MIN_VAL = 0x1L
MAX_VAL = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

def mkprivkey():
    key = SYS_RAN.randint(MIN_VAL, MAX_VAL)
    key0 = key >> 192
    key1 = (key >> 128) & 0xffffffffffffffff
    key2 = (key >> 64) & 0xffffffffffffffff
    key3 = key & 0xffffffffffffffff

    return hexlify(PACKER.pack(key0, key1, key2, key3))

```

In my [testing](https://gist.github.com/mbogosian/8488da5bda5d75651e25), the above is about an order of magnitude faster, even after normalizing your creation of SystemRandom instances and removing your test to see if you've exceeded the max value (per username_1 username_1's suggestion):

```
% time python ./test_ecdsaprivkey.py
mkprivkey:          0.016 ms avg
create_private_key: 0.168 ms avg
python ./test_ecdsaprivkey.py  9.99s user 11.00s system 86% cpu 24.388 total

```

Of course, this probably doesn't matter unless you're creating tens of thousands of keys.


---

### Answer by username_3 on 2018-01-16. Score: 0

`import os
import binascii
private_key = binascii.hexlify(os.urandom(32)).decode()
print("private key = " + private_key)`

> **Comments:**
> **username_4**: Welcome to Bitcoin.SE! Whilst this may theoretically answer the question, [it would be preferable](//meta.stackoverflow.com/q/8259) to include some explanation of your code too so that people can understand how it works and what it does  

---

