{"id":21331577,"url":"https://github.com/lukechampine/frand","last_synced_at":"2025-04-07T06:10:21.487Z","repository":{"id":44439534,"uuid":"194595451","full_name":"lukechampine/frand","owner":"lukechampine","description":"A fast userspace CSPRNG","archived":false,"fork":false,"pushed_at":"2024-10-07T18:20:46.000Z","size":36,"stargazers_count":89,"open_issues_count":1,"forks_count":11,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-31T05:04:14.529Z","etag":null,"topics":["chacha","csprng","rng"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lukechampine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-01T03:45:25.000Z","updated_at":"2025-03-04T20:44:34.000Z","dependencies_parsed_at":"2024-12-31T06:11:01.679Z","dependency_job_id":"89858abd-81c4-43db-a637-4bece1fe1689","html_url":"https://github.com/lukechampine/frand","commit_stats":{"total_commits":19,"total_committers":2,"mean_commits":9.5,"dds":"0.052631578947368474","last_synced_commit":"38046b4646b33fdfde3209ae91e92adec629e683"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukechampine%2Ffrand","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukechampine%2Ffrand/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukechampine%2Ffrand/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukechampine%2Ffrand/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukechampine","download_url":"https://codeload.github.com/lukechampine/frand/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247601448,"owners_count":20964864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chacha","csprng","rng"],"created_at":"2024-11-21T22:42:33.024Z","updated_at":"2025-04-07T06:10:21.467Z","avatar_url":"https://github.com/lukechampine.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"frand\n-----\n\n[![GoDoc](https://godoc.org/lukechampine.com/frand?status.svg)](https://godoc.org/lukechampine.com/frand)\n[![Go Report Card](http://goreportcard.com/badge/lukechampine.com/frand)](https://goreportcard.com/report/lukechampine.com/frand)\n\n```\ngo get lukechampine.com/frand\n```\n\n`frand` is a fast CSPRNG in userspace, implemented as a lightweight wrapper\naround the [`(math/rand/v2).ChaCha8`](https://go.dev/src/math/rand/v2/chacha8.go) generator. The initial\ncipher key is derived from the kernel CSPRNG, after which [no new entropy is\never mixed in](https://blog.cr.yp.to/20140205-entropy.html).\n\nThe primary advantage of `frand` over `crypto/rand` is speed: when generating\nlarge amounts of random data, `frand` is 20x faster than `crypto/rand`, and over\n100x faster when generating data in parallel. `frand` is also far more\nconvenient to use than `crypto/rand`, as its methods cannot return errors, and\nhelper methods such as `Intn` and `Perm` are provided. In short, it is as fast\nand convenient as `math/rand`, but far more secure.\n\n## Design\n\n`frand` was previously implemented as a [FKE-CSPRNG](https://blog.cr.yp.to/20170723-random.html).\nSince the addition of `ChaCha8` in Go 1.23, this is no longer necessary, as the\nstdlib generator is equally fast and secure. If you're curious about the old\nimplementation, you can read about it [here](https://github.com/lukechampine/frand/blob/3f951cc7c03d029aba12f89106666489fd8c769b/README.md).\n\nCalls to global functions like `Read` and `Intn` are serviced by a `sync.Pool`\nof generators derived from the master generator. This allows `frand` to scale\nnear-linearly across CPU cores, which is what makes it so much faster than\n`crypto/rand` and `math/rand` in parallel benchmarks.\n\n## Security\n\nThis is a slightly hot take, but I do not believe there is a meaningful\ndifference in security between using `crypto/rand` and a `crypto/rand`-seeded\nChaCha8 generator. There are caveats, of course: for example, since the\ngenerator is in userspace, it is somewhat easier to access its internal state\nand predict future. But if an attacker can access the internal state of your\nprogram, surely you have bigger fish to fry. If `crypto/rand` makes you feel\nsafer, great, use it. But I don't think it's actually any more secure.\n\nEven if you aren't comfortable using `frand` for critical secrets, you should\nstill use it everywhere you would normally use an insecure PRNG like\n`math/rand`. Go programmers frequently use `math/rand` because it is faster and\nmore convenient than `crypto/rand`, and only use `crypto/rand` when \"true\"\nrandomness is required. This is an unfortunate state of affairs, because misuse\nof `math/rand` can lead to bugs or vulnerabilities. For example, using\n`math/rand` to generate \"random\" test cases will produce identical coverage from\nrun-to-run if the generator is left unseeded. More seriously, using `math/rand`\nto salt a hash table may make your program [vulnerable to denial of service attacks](https://stackoverflow.com/questions/52184366/why-does-hashmap-need-a-cryptographically-secure-hashing-function).\nSubstituting `frand` for `math/rand` would avoid both of these outcomes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukechampine%2Ffrand","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukechampine%2Ffrand","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukechampine%2Ffrand/lists"}