-
Notifications
You must be signed in to change notification settings - Fork 30
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
integrate with standard Read
/Write
IO traits
#227
Comments
Write
for relevant typesRead
/Write
for relevant types
Read
/Write
for relevant typesRead
/Write
IO traits
I'll take a closer look at this ASAP, but for now I very much agree with leaving |
AEAD example Hash example |
Yes, I think this would be good to support. I'm unclear, though, how to directly convert between the streaming API and the
For the output size, this isn't something that Orion currently exposes in the safe API. And if users want to set it, then they can grab the For the "buffer", I'm not sure which buffer you mean. If users want to buffer the reader, they can use a |
I think I understand now, I think I misunderstood the purpose of |
I see your point, in that this can be tricky. Especially since streaming write directly to an output, and has no internal state. Perhaps, in that case each call to I'll have to think about this one a bit more. If we don't find a solution to this, I definitely think that we should start with adding the integration to the hashing primitives and non-streaming AEAD, and then see how that turns out. WDYT? I was also thinking that perhaps the naming of the functions for non-streaming AEAD could be made a bit less generic. How about In any case, I really like the idea behind the hashing primitives so far. This should definitely go in. Regarding another |
Oh, interesting. Yeah this probably would work. Instead of having a single call to e.g.
Yes, agreed. Hashing is pretty straightforward here. Basically just consume any reader and output the digest. Though I do see where the user may want to control the size of the buffer we read into (which I see now is probably what you meant above). Maybe we could do something like internally allocate a
I like these names. Not sure about For the hash names, are you still good with |
Right now I'm kind of lost in all these buffers and read/write directions/sources tbh. Do you perhaps have a small example?
Fine by me. The only downside I see is the small added consistency with the existing method naming of
Good point. I very much like the
Almost tempting haha. |
Here's what the API might look like. let reader = File::open("file.txt")?;
let digest = orion::hash::digest_from_reader(reader)?; Nice and easy. Internal to the fn digest_from_reader(mut reader: impl Read) -> Result<Digest> {
// Start with a buffer of 1KB (not sure what this initial value should be)
let mut read_buffer = vec![0; 1024];
loop {
let bytes_read: usize = reader.read(&mut read_buffer)?;
if bytes_read == 0 { break; }
if bytes_read == read_buffer.len() {
// Double the size of the buffer if we filled it up last time.
read_buffer.extend(std::iter::repeat(0).take(read_buffer.len()));
}
// Hash the slice given by: &read_buffer[..bytes_read]
}
} |
That is a very straight-forward API indeed. Thanks for the example! I think this is a good approach. We can figure out a good buffer size and document it clearly. Assuming users of Edit: If we take such large buffers, we probably don't want to resize them dynamically though. |
Allocating a buffer of 256 KiB seems reasonable. Very few applications would be affected by that use of memory, and those that are can use the hazardous module and |
Just making sure, but this is the Regardless, sounds like a good plan. |
Yes, exactly. I meant |
Summary
The Rust ecosystem heavily integrates with
std
'sRead
andWrite
traits. It would be helpful to interoperate with these traits, especially in the context of theaead
andhash
modules.Example
Hashing
AEAD
I'm definitely open to suggestions on the API described here. Particularly, I'm not sure if we'd want convenience wrappers around the
*_copy
functions for the AEAD case. The copy functions are fairly general, and will allow for people to allocate buffers how they want. But there's probably a case to be made to provide a simpler type that just outputs aVec
of encrypted/decrypted data.In any case, the real advantage of implementing these APIs is that someone could do, for example, the following:
And it would work as expected. The big deal here is that large files should be read and hashed in pieces, which currently requires reaching into the
hazardous
module and using the "streaming interface" (theupdate
method). This looks something like the following.So it's longer, has a little more room for user error, and in general we probably just want to support the existing IO traits.
I already started the implementation, and I'll post a draft PR soon.
Also, I considered making
AsyncRead
andAsyncWrite
part of this issue/PR, but that seems like it should be its own thing. There's talk about integrating those traits into the standard library some time soon, so maybe we should hold off until then.The text was updated successfully, but these errors were encountered: