Rust Libs
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- date: 2025-06-09 url: https://hackmd.io/lTm6WsLWQMChYg4-IgLdNw --- People: Josh Triplett, Diggory, TC, Amanieu # Notes JoshT: My expectation: the trait should exist in core. The concept of generating random numbers doesn't require OS. But the (default) random source could be in std and getrandom could be in std. Diggory: This might require initialisation. Josh: - `trait RandomSource` - in core, infallible - `struct DefaultRandomSource` - in std - `fn getrandom(...) -> io::Result<...>` - in std, fallible - Or: `impl Read for DefaultRandomSource` TC: need for a non-blocking API. Alternative: - `fn is_getrandom_ready()`: yes, not yet, other error Amanieu: ```rust fn secure_random_source() -> Result<DefaultRandomSource, Error>; ``` Josh: ```rust struct DefaultRandomSource; // May fail: impl Read for DefaultRandomSource { .. } // Can't fail (would panic instead) impl RandomSource for DefaultRandomSource { .. } ``` Diggory: in Rand we have two traits -- one with error handling `TryRngCore` and one without`RngCore`. And we have a wrapper for converting one from the other. Amanieu: Do people use `TryRngCore`? Amanieu: Feel strongly that the trait in core should be without error handling. Josh: We can add the "try" version later in the future. If you want something that has the possibility of failing, you can call `getrandom` yourself. TC: We were talking about the random source implementing `Read`. And Read is fallible. Amanieu: That was an alternative proposal instead of the `getrandom` function. Josh: Could we use `Read` as the implementation of the random source. It's fallible and couldn't possible be put in core (and not clear path forward). We can't put `io::Error` into core. We might be able to put `io::Error` into `alloc` but core should be able to have the random trait. TC: Why wouldn't we implement `Read` for `DefaultRandomSource`? That seems extremely useful. Josh: That is potentially a workable idea. Can we just provide `impl Read` for `DefaultRandomSource` -- could you then call call read/read_buf and have that be your source? Diggory: Yes. Josh: TC, would that (`impl Read for default random source?`)? TC: Have we solved reading into uninitialized buffers? Josh: `Read` supports that but we need to stabilize it. (Someone): See also: https://blog.sunfishcode.online/writingintouninitializedbuffersinrust/ TC: I think user should use that most of the time. I still like the idea to stabilize the unsafe primitive as well -- we'll need to implement that anyway. Diggory: would the `DefaultRandomSource` implement both `Read` and the `RandomSource` trait? Josh: Yes, you would get "fill a buffer" from read and the higher-level functionality like get `i32`. Josh: Why does rng::Source implement so many different ways (next_u32, next_u64, fill_bytes) of getting individual values? Diggory: Some rngs are faster doing that. Josh: Is there a reason why all these are required and some of them can't be implemented (by default) in terms of the other ones? Diggory: We provide implementations people can call, but different RNGs want to provide a different interface; block-based generators would provide `fill_buf`, word-based interfaces would provide `next_u64`. Josh: We're working on something in the language that would help here: say that these things all have default implementations that depend on each other but you'd need to implement at least one. TC: Usecase for why non-blocking is important: you're writing an SSH implementation in rust. You want to write this using async rust (you have executors and all that). You need to generate server-side keys. That's a difficult problem -- SSH is one of the first things the OS starts. OS might start you early before it's ready to generate randomness. So you want to wait until the OS is ready. But you're also running an async executor. You can't call "getrandom blocking" because that can block you. That's a correctness problem. I'd prefer to call a non-blocking mode so it returns an error and then could signal to the OS that I'm not ready to start up yet. And try again later. If I can't do that I'm not sure how to write the server correctly. Josh: Sounds like you're ready to rely on OS's "once it's ready, it'll never be not ready". TC: For the time being yes. Josh: If we're going to provide a "is_random_ready" function, would that work? TC: Yes. TC: Writing an SSH server is something that's not obscure -- something we really should support. So we really need to nail this solution. Josh: No objection to having an `is_random_ready` function. An OS that doesn't have it always fails. An OS that has it ready always can return `true`. Just necessarily ready to stabilize this at the same time. Diggory: Sounds like that could go against "not easy to misuse"? Josh: You can just not call it, and still use the TC+Josh: Need to document that (a) once it returns success, DefaultRandomSource won't block, and (b) that if a source is ready it won't stop being ready. Josh: `getrandom` would only block when the OS's randomness is not ready yet. Amanieu: for something like Tokio you need to wake up once something is ready. Typically you'd open /dev/random and wait for it to be ready. Josh: Is `is_random_ready` something that could go to the std. But something that asynchronously watches the OS randomness to be ready is not something we're not ready add yet (because we don't have any executor etc. to add it). Josh: If we had this set of interfaces (possibly `is_random_ready`), `DefaultRandomSource` that implements Read and Rand. What should the `RandomSource` have? Diggory: Depends on applications. Is this to be used as a replacement for `Rand`? Josh: What is the performance delta of using a word-based generation to do `fill_buf` compared to having it implement multiple functions instead of one. Diggore: Maybe like 20% loss or something? Depends on your application. Josh: Definitely non-trivial. Amanieuu: Are you converting a single word into multiple bytes? Diggory: Yes, you're using the same input. Amanieu: That should still optimize away. Diggory: If you know the length & alignment. If you don't, maybe not. Josh: What we want teh properties of the interface be? DefaultRandomSource: OS-based and secure. We haven't talked about any sources for insecure randomness. Diggory: The hashmap initialisation uses the insecure implementation already. Josh: You're talking about calling `getrandom` without the grnd flag? Effectively using `random` rather than `urandom`? Josh: in the spirit of hard to misuse -- we should give you secure random. And maybe require you to call into another library for insecure random number. Diggory: Should `RandomSource` have the implication be that it should provide secure random bytes? Amanieu: No. Diggory: Should we have a marker trait that declares this to be secure? Josh: There's different meanings of "secure" here. Amanieu: I'd expect anyone who needs secure random data to just use the `DefaultRandomSource` directly. Josh: There is an argument for why someone building a cryptographic library to use a non-default source: testing and fuzzing -- e.g. getting a seedable source (to verify you get the same key out). Amanieu: In that case you wouldn't require an secure trait bound, just any random trait bound. Either you allow a different source for testing. Or you allow for Josh: Seedable doesn't imply insecure. Amanieu: Don't see much use for the marker trait. We should ship without it. Josh: We should ship without it _first_. We need to see what people expect. Not clear whether we want to provide a generic argument for seeding. There are usecases for having a marker saying this is definitely CSRNG. Josh: We may want to consider having a crypto random source. But we don't want to provide a way for someone to fake out a crypto random source for testing. Would be nice to dodge those questions. Amanieu: Can be added later if needed. Amanieu: Good to have 2 sources: (1) default random source: give me the best random source you can provide (always succeeds). (2) Secure rando source: the platform will fail on a platform that doesn't have a secure random source. Josh: Concern about the naming ("default" implying possibly an insecure source) Amaniou: There's a random source that always succeeds and one that always fails. Josh: Why wouldn't we provide best effort at all? Is there anything other than wasm that we don't want people to copy? Josh: Are you saying that the "insecure" source is PRNG? Amanieu: There's a value in having a "thread RNG" and secure RNG. Diggory: Thread RNG in rand is secure. Don't see necessarily a lot of value. Josh: The concept of an insecure source makes sense for a different reason: the insecure one doesn't have to have its algorithm changed in the future. So it can always to stay the same and then have it be the source for fuzzing, games etc. # Meeting 2025-06-09 - Random number generation in the standard library Josh: The goal of the original library ACP was to get 1) An interface in core for random sources, and 2) A default random source in std based on system randomness. 3) *Eventually*, to build some basic functionality atop that, like "choose an item from an iterator" or "roll a random number in a range". The goal isn't to have all the functionality of rand for every one of its many use cases, but to have enough of the functionality to satisfy two common use cases: "I want to build a simple game" and "I want to get randomness to use for an API key or similar". dhardy: - A random source (getrandom). Probably needs to have error handling of some kind. Probably needs to support settings a custom source in some cases, but without letting some library in the dependency tree override the default with an insecure source. - A default RNG (thread-local or direct fast OS interface); a `rand::rng` replacement. Probably wants a trait like `rand::RngCore`. - This is just choosing parts of rand to incorporate and possibly simplify (e.g. maybe drop portable reproducibility guarantees, or not). Less important since with (1) and (2) the rand crate could potentially drop all dependencies and be decently small. TC: For `getrandom`, agree we'll want error handling, and we'll also want to talk about how to support use cases that need its blocking behavior and those that need its nonblocking one (i.e. `GRND_NONBLOCK`). Personally, I'd also like to see us eventually stabilize something that works without `std` (maybe, e.g., in `core::arch`, in the spirit of `breakpoint`) that uses the features of the target CPU (maybe it'd only be available on such targets). These instructions are now widespread. I'd see this function as being low level and e.g. only returning a single word. --- Random source requirements: - Secure - Trait based? [May help with `no_std` compatibility](https://github.com/rust-lang/rust/issues/130703#issuecomment-2648880629), but may not be useful. - Error reporting. Or not: https://github.com/golang/go/issues/66821. Do the error values matter? Likely only for debugging. Can code safely recover? Can it be useful in selecting between multiple sources? BrianSmith [says](https://github.com/rust-lang/rust/issues/130703#issuecomment-2651498888) "Not everybody can use an API that abort()s or panics, as some coding standards do not allow any abort() or (reachable) panic at all." - Filling an uninitialized buffer? Motivation in `getrandom` is partly about using Miri's initialization proof for randomization. - Generation of `u32` / `u64`? - Potentially-insecure seeding? - Option to specify a custom source, maybe like `#[global_allocator]` or using [RFC 3632](https://github.com/rust-lang/rfcs/pull/3632)? *But* libraries in the dep tree should not be able to replace the source for security reasons. See [this comment](https://github.com/rust-lang/rust/issues/130703#issuecomment-2508919949) and the next.... Default random source requirements (trait based): - Secure - Fast? - Is this the same as above, or a user-space PRNG over it? jstarks says "please never do this", yet `rand::rng` does because it cannot guarantee the perf. of the system RNG. - Platform-specific? - Byte-fill and next-word interfaces? - No error reporting? - Trait-based, with alternatives? Alternative RNGs: - Do these belong in `core`? - Allow seeding with expectations of reproducibility newpavlov [suggests](https://github.com/rust-lang/rust/issues/130703#issuecomment-2650807432) (at least) three sources in `std`: `SecureRandomSource`, `InsecureRandomSource`, `ThreadRng` --- "Easy to use" vs "hard to misuse" in API design, and tradeoffs like interfaces with error handling vs interfaces that are harder to misuse. Trait design and error reporting. Entropy source (e.g. `getrandom`) vs default random source. dhardy: "PRNGs like PCG or Xoshiro are much smaller and somewhat faster than CSPRNGs like ChaCha, so there's incentive for both to exist." Lower-priority topics: - Seedability: traits, vs RNG-specific interfaces. Do we want this in core? - RNG jump support?

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully