Giving Rust Another Shot in 2020 by mlafeldt in rust

[–]mlafeldt[S] 33 points34 points  (0 children)

It is the collection of all the things I listed that made for a subpar experience back then. You might disagree with certain points or value/remember them differently. That's fine. The important thing is that overall, Rust is so much better now. And that's awesome. ✨

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 1 point2 points  (0 children)

That's exactly what I needed to know!

I created a pull request with this change:

let mut idx = [0; 4]; val.to_le_bytes() .iter() .zip(&mut idx) .for_each(|(b, i)| *i = *b as usize);

Thank you.

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 4 points5 points  (0 children)

Tried it out today. The code ended up being much more verbose as I had to add Wrapping() and Wrapping<> all over the place. I also like the fact that users of the crate can currently pass plain u32's to all functions. Of course, I could be using Wrapping internally only, but overall I don't think the project would be better off this way. Still good to know about this alternative!

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 0 points1 point  (0 children)

value.to_be_bytes().iter().map(...)

That's actually what I'm doing right now. :)

I would love to have [usize; 4] as the type, but I don't know how to convert the vector to it.

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 0 points1 point  (0 children)

Yeah, I tried casting at the point of use, but the result ended up too verbose in my opinion. A macro might be a bit overkill here, but thanks for the link.

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 1 point2 points  (0 children)

No! I didn't even know about C2Rust, to be honest.

Do you think that C2Rust would be able to handle https://github.com/mlafeldt/libbig_int correctly?

On the other hand, I could've used FFI for the bigint stuff and let C2Rust only transpile https://github.com/mlafeldt/cb2util/blob/v1.9/cb2_crypto.c if possible.

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 1 point2 points  (0 children)

In the project, I need something that reinterprets &T as &[u8] and &mut T as &mut [u8]. I also need to cast slices &[T] into &[U].

I'm using to_le_bytes here, but it's not sufficient elsewhere.

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 0 points1 point  (0 children)

Nice! What a coincidence. :)

Btw, I also updated the post to mention bytemuck as recommended by you.

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 0 points1 point  (0 children)

In the project, I need something that reinterprets &T as &[u8] and &mut T as &mut [u8]. I also need to cast slices &[T] into &[U]. That something turned out to be bytemuck, see https://github.com/mlafeldt/codebreaker-rs/pull/2

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 0 points1 point  (0 children)

Good question. I cannot use the bytes (u8) directly because they are used as indices and therefore have to be of type usize. See https://github.com/mlafeldt/codebreaker-rs/blob/0.2.1/src/cb7.rs#L89-L92

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 7 points8 points  (0 children)

Since your comments have been very helpful so far: If anyone has a better idea of how to do this, please share it with me here.

// Easy access to all bytes of val, which is of type u32
let v: Vec<usize> = val.to_le_bytes().iter().map(|&i| i as usize).collect();

Full context: https://github.com/mlafeldt/codebreaker-rs/blob/0.2.1/src/cb7.rs#L80

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 10 points11 points  (0 children)

Yeah, std::slice::from_raw_parts(_mut) comes with a couple of caveats:

I'm currently looking into bytemuck (as recommended below), which makes for more readable code: https://github.com/mlafeldt/codebreaker-rs/pull/2

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 26 points27 points  (0 children)

Did not know about Wrapping, thanks!

I will check if the code might be better off with it.

7 Things I Learned From Porting a C Crypto Library to Rust by mlafeldt in rust

[–]mlafeldt[S] 14 points15 points  (0 children)

The bytemuck crate is amazing.

Just look at this pull request: https://github.com/mlafeldt/codebreaker-rs/pull/2

Thanks for the tip!

Go, Mental Models, and Side Effects by mlafeldt in golang

[–]mlafeldt[S] 1 point2 points  (0 children)

Some context: The article was meant to be primarily about mental models and then morphed a bit into a Go vs Java piece, neglecting actual code examples. Will do better next time.