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

Provide an easier-to-use rand API #728

Open
briansmith opened this issue Nov 26, 2018 · 2 comments
Open

Provide an easier-to-use rand API #728

briansmith opened this issue Nov 26, 2018 · 2 comments

Comments

@briansmith
Copy link
Owner

briansmith commented Nov 26, 2018

Consider adding a function like this to ring::rand.

pub fn value<T: Default + AsMut<[u8]>>(rng: &SecureRandom) -> Result<T, error::Unspecified> {
    let mut r: T = Default::default();
    rng.fill(r.as_mut())?;
    Ok(r)
}

Then we could initialize fields like this:

struct Key {
   value: [u8; KEY_LENGTH],
}

impl Key {
    fn new(rng: &rand::SecureRandom) -> Result<Self, error::Unspecified> {
        Self { value: rand::value(rng) }
    }
}

Ideally rand::value() would work for arrays of all primitive integer types (usize, u128, u64, u32, u16, u8) and vector types. Thus we'd need to replace the AsMut<[u8]> bound with a more general one that admits those types.

@sconybeare
Copy link

I decided to take a stab at this. I haven't tried to make anything work for vectors, but I've implemented this with a trait bound that allows for the construction of primitive integer types, as well as fixed sized arrays thereof. The lengths of those arrays are arbitrarily limited to 32 elements because we don't have support for generic compile-time integers, and because I had to pick a number.

@briansmith
Copy link
Owner Author

In the interim, until we get this all sorted out, I created a new function:

pub fn generate<T: RandomlyConstructable>(
    rng: &SecureRandom,
) -> Result<Random<T>, error::Unspecified> { ... }

I implemented RandomlyConstructable for u8 arrays of lengths 4, 8, 16, 32, 48, and 64, since those are the lengths I know to be useful for ring users.

Notably, I was able to do so without using any unsafe. I think that's something we should strive for in a more generic implementation.

The lengths of those arrays are arbitrarily limited to 32 elements because we don't have support for generic compile-time integers, and because I had to pick a number.

[u8; 64] and [u8; 48] are commonly needed. In my implementation I avoid using the standard library's AsRef/AsMut implementations for this reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants