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

feat: Allow public access to bytes #250

Closed
wants to merge 2 commits into from

Conversation

tbraun96
Copy link

@tbraun96 tbraun96 commented Oct 22, 2023

When building a protocol, we sometimes make use of generic bytes to allow variable use of subprotocols, and don't want to have to add the overhead of serialization. By allowing public access to the inner fields (whether directly or indirectly via a function), everything works.

Allow public access to bytes
@tbraun96 tbraun96 changed the title Allow public access to bytes feat: Allow public access to bytes Oct 22, 2023
@@ -10,7 +10,7 @@ macro_rules! newtype_buffer {
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct $name {
bytes: Vec<u8>,
pub bytes: Vec<u8>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will not merge this: it does not provide faster reference than as_ref and this allows to mutually access bytes which I do not think is a) idiomatic Rust and b) good and safe API design.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need the ability to construct this given a Vec<u8>. The AsRef<u8> impl is only good for reading the data.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, if you're interesed in idiomatic rust, we could do:

impl From<Vec<u8>> for $name {
    fn from(bytes: Vec<u8>>) -> $name {
        $name { bytes }
    }
}

@@ -31,7 +31,7 @@ macro_rules! newtype_buffer {

impl<'a> $name_ref<'a> {
/// Construct a new container around this reference version
fn new(bytes: &'a [u8]) -> $name_ref<'a> {
pub fn new(bytes: &'a [u8]) -> $name_ref<'a> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementing this requires an assertion on the length of bytes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, especially if we're dealing with pointer arithmetic under the hood. In idiomatic rust would use result types instead of assertions, especially if we decide to hand over partial control of building these wrappers to the user.

@tbraun96
Copy link
Author

@thomwiggers let me know what approach you're okay with and I'll amend the PR. Thanks.

@thomwiggers
Copy link
Contributor

Having remembered/looked up what API choices I made, the only supported way of constructing these types is using:

https://docs.rs/oqs/0.9.0/oqs/kem/struct.Kem.html#method.public_key_from_bytes
https://docs.rs/oqs/0.9.0/oqs/kem/struct.Kem.html#method.ciphertext_from_bytes
https://docs.rs/oqs/0.9.0/oqs/sig/struct.Sig.html#method.public_key_from_bytes
https://docs.rs/oqs/0.9.0/oqs/sig/struct.Sig.html#method.signature_from_bytes
https://docs.rs/oqs/0.9.0/oqs/sig/struct.Sig.html#method.secret_key_from_bytes
https://docs.rs/oqs/0.9.0/oqs/kem/struct.Kem.html#method.secret_key_from_bytes

Any way of constructing them without going through oqs::kem::Kem or oqs::sig::Sig instances is unsafe and should not be supported as we rely on the error checking done in these methods.

Any performance difference in using these methods versus directly contructing these types is either up to error checking (which is not a bug) or a bug in compiler optimizations, which should be reported to the Rust project.

@thomwiggers thomwiggers added invalid This doesn't seem right wontfix This will not be worked on labels Oct 23, 2023
@tbraun96
Copy link
Author

Having remembered/looked up what API choices I made, the only supported way of constructing these types is using:

https://docs.rs/oqs/0.9.0/oqs/kem/struct.Kem.html#method.public_key_from_bytes https://docs.rs/oqs/0.9.0/oqs/kem/struct.Kem.html#method.ciphertext_from_bytes https://docs.rs/oqs/0.9.0/oqs/sig/struct.Sig.html#method.public_key_from_bytes https://docs.rs/oqs/0.9.0/oqs/sig/struct.Sig.html#method.signature_from_bytes https://docs.rs/oqs/0.9.0/oqs/sig/struct.Sig.html#method.secret_key_from_bytes https://docs.rs/oqs/0.9.0/oqs/kem/struct.Kem.html#method.secret_key_from_bytes

Any way of constructing them without going through oqs::kem::Kem or oqs::sig::Sig instances is unsafe and should not be supported as we rely on the error checking done in these methods.

Any performance difference in using these methods versus directly contructing these types is either up to error checking (which is not a bug) or a bug in compiler optimizations, which should be reported to the Rust project.

Perfect. I did not see these in the documentation, likely because I was looking at the structs themselves instead of the Kem itself that has metadata on the byte lengths.

@thomwiggers
Copy link
Contributor

I suppose we can improve the docs for the types a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right wontfix This will not be worked on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants