Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add system random to stdlib: std/sysrand #16459

Merged
merged 69 commits into from
Feb 12, 2021
Merged

Conversation

ringabout
Copy link
Member

@ringabout ringabout commented Dec 24, 2020

Cryptographically secure pseudorandom number generator

https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator

Many popular and mature programming languages put system random on their standard library


libsodium
https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c

blog:
https://paragonie.com/blog/2016/05/how-generate-secure-random-numbers-in-various-programming-languages

implementation:
image

future work

It need not hold up this PR being merged, but if this is merge-worthy then I think it is probably better to use this instead of a high resolution clock in lib/pure/random.nim:randomize.

oids can also benefits from this PR(use a secure seed).

If stdlib can accept UUID, the module will benefit from this PR too.

It can also be used to generate salts, keys or initialization vectors.

tests/magics/t10307.nim Outdated Show resolved Hide resolved
@ringabout ringabout changed the title Didodido add secrets to stdlib Dec 24, 2020
@ringabout ringabout changed the title add secrets to stdlib add system random to stdlib Dec 24, 2020
lib/std/secrets.nim Outdated Show resolved Hide resolved
lib/std/secrets.nim Outdated Show resolved Hide resolved
lib/std/secrets.nim Outdated Show resolved Hide resolved
lib/std/secrets.nim Outdated Show resolved Hide resolved
lib/std/secrets.nim Outdated Show resolved Hide resolved
@ringabout ringabout marked this pull request as draft December 27, 2020 09:48
lib/std/secrets.nim Outdated Show resolved Hide resolved
@ringabout ringabout marked this pull request as ready for review January 24, 2021 04:08
lib/std/sysrand.nim Outdated Show resolved Hide resolved
lib/std/sysrand.nim Outdated Show resolved Hide resolved
lib/std/sysrand.nim Outdated Show resolved Hide resolved
Copy link
Member

@timotheecour timotheecour left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM; @Araq how about we merge this now, and we can do followup PR's to fix the remaining bugs; since it's a new module it's fine IMO to do this so we can make faster progress (maybe with a note: experimental module, unstable API)

@Clyybber
Copy link
Contributor

Clyybber commented Feb 5, 2021

LGTM; @Araq how about we merge this now, and we can do followup PR's to fix the remaining bugs; since it's a new module it's fine IMO to do this so we can make faster progress (maybe with a note: experimental module, unstable API)

We cannot merge something with potential security issues/bugs like this, especially when it should cryptographically secure. Let's fix the bugs instead of rushing.

@timotheecour
Copy link
Member

timotheecour commented Feb 5, 2021

We cannot merge something with potential security issues/bugs like this, especially when it should cryptographically secure. Let's fix the bugs instead of rushing.

What I'm arguing for here is to allow iterating in a more effective way on new modules (or even new APIs in existing modules), including this one. This could be as simple as:

# in std/sysrand.nim
when not defined(nimExperimentalSysrand): static: doAssert "experimental module, unstable API"
# rest of code ...

so that:

  • this module remains hidden by default, but people can easily try it in devel with explicit flag -d:nimExperimentalSysrand; more eyeballs => higher likelyhood to find bugs/design issues
  • more than 1 person can easily contribute to it
  • no need to constantly rebase long running PR's and resolve conflicts since they'd be merged faster
  • we can more freely iterate without fear of breaking changes for regular devel users

Unlike the proposal discussed in nim-lang/RFCs#310, there'd be no need for std2 namespace, and no need for introducing an experimental namespace (which has the issues of causing problems when module is moved), since the only difference once module is stabilized is that the flag -d:nimExperimentalFoo would not be needed anymore;

This is essentially a lightweight form of --experimental:foo that can be used for new (non-trivial) modules/API's.
(refs timotheecour#575)

Copy link
Contributor

@dom96 dom96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beautiful, a perfect example of something that should be in the stdlib.

I'm mostly writing this because I feel like I very often reject PRs for new modules to the stdlib, it's nice to accept a case that I think does deserve to be in the stdlib :)

The API is also solid and docs look good. Implementation we can always easily improve as long as API doesn't need to change so IMO we can merge this now tbh.

@dom96
Copy link
Contributor

dom96 commented Feb 11, 2021

We cannot merge something with potential security issues/bugs like this, especially when it should cryptographically secure. Let's fix the bugs instead of rushing.

Yes, we can. We just need to make it clear that the module is new, all this needs is a warning in the docs, something like:

Warning: This module was added in Nim 1.6. If you are using it for crypto purposes then keep in mind that so far this has not been audited by any security professionals, as such may not be secure.

In fact, we should keep this warning until a reputable company does audit it and then link to the audit in the docs.

@timotheecour timotheecour changed the title add system random to stdlib add system random to stdlib: std/sysrand Feb 12, 2021
@timotheecour timotheecour merged commit 18c24eb into nim-lang:devel Feb 12, 2021
@timotheecour
Copy link
Member

timotheecour commented Feb 12, 2021

Yes, we can. We just need to make it clear that the module is new, all this needs is a warning in the docs, something like:

indeed. This is exactly what timotheecour#575 is about: avoiding analysis paralysis where a PR slowly collects bitrot over time, and needs constant rebasing. More eyes = more bugfixes.
We can hide this behind when defined(nimExperimentalSysrandom) in a next PR to allow fixing API in meantime as needed, until it stabilizes.

reputable company does audit it and then link to the audit in the docs

it can't hurt but I'm not sure if it buys you much in practice beyond a marketing argument; this module depends on some parts of stdlib (system.nim) and compiler for correctness; that one-time audit wouldn't cover those, and even if it did it wouldn't guard against regressions.

@euantorano
Copy link
Contributor

euantorano commented Feb 18, 2021

This is completely broken on NetBSD at the moment (and likely Dragonfly, though I haven’t tested there yet).

Note that there are a few existing Nimble packages that aim to achieve the same thing, like:

I would almost always base this kind of code on the fantastic libsodium, who’s approach can be found here: https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c

I’m very happy to see this module get added to the stdlib though :)

@timotheecour
Copy link
Member

timotheecour commented Feb 18, 2021

@euantorano PR welcome; also regarding running netbsd in CI

for netbsd, see also this comment #16459 (comment) which has some potential solutions

@ringabout
Copy link
Member Author

see 18c24eb#r47295760

@euantorano
Copy link
Contributor

@euantorano PR welcome; also regarding running netbsd in CI

for netbsd, see also this comment #16459 (comment) which has some potential solutions

I have some nightly tests running here already: http://jenkins.euantorano.co.uk/job/Nim/124/console - it just runs on a schedule rather than on every PR/commit which is good enough for now until we get some of the failures fixed.

see 18c24eb#r47295760

Yep, looks like it. It was broken when I commented, likely due to the nature of it running nightly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
TODO: followup needed remove tag once fixed or tracked elsewhere
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants