[Python-ideas] PEP 504: Using the system RNG by default

Tim Peters tim.peters at gmail.com
Thu Sep 17 17:11:44 CEST 2015

[Nick Coghlan <ncoghlan at gmail.com>]
> As far as implementation goes, based on a separate discussion at
> https://github.com/pyca/cryptography/issues/2347, I believe the
> essential cases can all be covered by:
>     def random_bits(bits):
>         return os.urandom(bits//8)
>     def random_int(bits):
>         return int.from_bytes(random_bits(bits), byteorder="big")
>     def random_token(bits):
>         return base64.urlsafe_b64encode(random_bits(bits)).decode("ascii")
>     def random_hex_digits(bits):
>         return binascii.hexlify(random_bits(bits)).decode("ascii")
> So if you want a 128 bit (16 bytes) IV, you can just write
> "secrets.random_bits(128)". Examples of all four in action:
> ...

Probably better to wait until Steven starts a new thread about his PEP
(nobody is ever gonna look at _this_ thread again ;-) ).

Just two things to note:

1. Whatever task-appropriate higher-level functions people want, as
you've shown "secure" implementations are easy to write for someone
who knows what's available to build on.  It will take 10000 times
longer for people to bikeshed what "secrets" should offer than to
implement it ;-)

2. I'd personally be surprised if a function taking a "number of bits"
argument silently replaced argument `bits` with `bits - bits % 8`.  If
the app-level programmers at issue can't think in terms of bytes
instead (and use functions with a `bytes` argument), then, e.g.,
better to raise an exception if `bits % 8 != 0` to begin with.  Or to
round up, taking "bits" as meaning "a number of bytes covering _at
least_ the number of bits asked for".

More information about the Python-ideas mailing list