[Python-Dev] PEP 506 secrets module

Steven D'Aprano steve at pearwood.info
Sat Oct 17 05:50:50 EDT 2015

On Sat, Oct 17, 2015 at 03:26:46AM +1100, Steven D'Aprano wrote:
> On Fri, Oct 16, 2015 at 06:35:14PM +0300, Serhiy Storchaka wrote:
> > I suggest to add only randrange(). randint() is historical artefact, we 
> > shouldn't repeat this mistake in new module. The secrets module is not 
> > good way to generate dice rolls. In most other cases you need to 
> > generate integers in half-open interval [0; N).
> > 
> > And randbelow() is absolute redundant. Random._randbelow() is 
> > implementation detail and I inclined to get rid of it (implementing 
> > randrange() in C instead).
> This was discussed on Python-Ideas, and there was little consensus there 
> either. (Looks like Tim Peters' prediction is coming true :-)
> I've also raised this issue on the python-list mailing list.

I've had some feedback on python-list. To summarise the various 
positions expressed so far:

    randbelow only:  3 in favour

    randint only:  1 neutral (neither opposed nor in favour)

    randrange only:  1 in favour, 1 against

    both randrange and randint:  2 in favour

(Total number of comments is more than the total number of posts, as 
some people expressed more than one opinion in the same post. As in, "I 
prefer X, but Y would be good too".)

So you can see there is nothing even close to consensus as to which API 
is best, which is an argument for keeping all three functions.

But significanly, only *one* of the commenters has claimed to have any 
significant experience in crypto work, and I will quote him:

    Having done quite a bit of serious crypto implementation over the 
    past 25 years, I don't recall ever wanting anything like randrange, 
    and if I did need it, I'd probably build it inline from randbelow 
    rather than force some hapless future code maintainer to look up the 
    specs on randrange.

    My opinion, FWIW: I like randbelow, because in modern crypto one 
    very frequently works with integers in the range [0,M-1] for some 
    large modulus M, and there is a constant risk of asking for 
    something in [0,M] when one meant [0,M-1].  One can eliminate this 
    risk, as randbelow does, by building in the -1, which normally 
    introduces a risk of making a mistake that gives you [0,M-2], but 
    the name "randbelow" seems like a neat fix to that problem.

    -- Peter Pearson

This matches what Serhiy suggests: in crypto, one normally only needs to 
generate the half-open interval [0...n). It also matches the reason why 
Tim Peters added randbelow in the first place.

As the author of the PEP, I'm satisfied by this argument, and will now 
state that my preferred option is to drop randint and randrange, and 
just keep randbelow.

My second choice is to keep all three functions.

I think it is fair to say that out of the three functions, there is 
consensus that randbelow has the most useful functionality in a crypto 
context. Otherwise, people seem roughly equally split between the three 
functions. There doesn't seem to be any use-case for the three argument 
version of randrange.


More information about the Python-Dev mailing list