# DRBG Rust implementation of the secure random number generator `CTR_DRBG` as defined by NIST [800-90A Rev.1](https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final). [![crates-badge][crates-badge]][crates-url] [![docs-badge][docs-badge]][docs-url] [![mit-badge][mit-badge]][mit-url] [crates-badge]: https://img.shields.io/crates/v/drbg [crates-url]: https://crates.io/crates/drbg [docs-badge]: https://docs.rs/drbg/badge.svg [docs-url]: https://docs.rs/drbg [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [mit-url]: https://github.com/dpottavio/drbg/blob/main/LICENSE `CTR_DRBG` is a cryptography secure pseudo-random number generator (CSPRNG) based on the AES block cipher. It may be used to generate encryption keys, nonces, or salts. By default, it is seeded with entropy from the operating system, but other entropy sources may be defined using the `Entropy` trait. The goal of this package is to create a CSPRNG that is secure by default, lightweight, and easy to use. ## Performance The performance of `CTR_DRBG` is dominated by AES encryption operations. Platforms that have AES instruction sets (e.g., AES-NI) should see significant performance gains. Passing additional info to the `fill_bytes` function does incur additional overhead as the info is input to the AES derivation function. ### Benchmarks The following benchmark measurements where taken on a Intel i5-8265U CPU @ 1.60GHz with AES-NI enabled. The measurements below are the average latency for reading random data. The sizes 16 and 32 bytes are used because they are typical for generating symmetric encryption keys. The 1 MiB test represents collecting bulk random data. The first set of measurements are taken without passing *additional info* to `fill_bytes`. While the second set of measurements are taken with 8 bytes of *additional info* to the call. *Additional info* is an optional parameter that adds additional input to the random number generation process. However, the info is passed through a derivation function that maps the info to an AES-block-sized message digest. Computing the digest does add additional overhead, but it is a one-time cost per call of `fill_bytes`. #### Without additional info |Random Data |Latency | |------------|--------------------| |16 (bytes) |144 (ns) | |32 (bytes) |167 (ns) | |1 (MiB) |1.5 (ms) ~ 655 MiB/s| #### With 8 bytes of additional info |Random Data |Latency | |------------|---------------------| |16 (bytes) |702 (ns) | |32 (bytes) |722 (ns) | |1 (MiB) |1.51 (ms) ~ 652 MiB/s| Overall the performance of this implementation of `CTR_DRBG` should be sufficient for most use-cases. Although passing additional info has a performance implications, it is an optional parameter. For bulk random data, the overhead of additional data is marginal compared to the random number generation process. To run the above benchmarks run the following command. Depending on your environment, you may need to force enablement of AES-NI. See the [aes](https://crates.io/crates/aes) crate for more details. ```bash cargo bench ```