-
Notifications
You must be signed in to change notification settings - Fork 85
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
argon2: Add parallel lane processing #149
Conversation
Thanks for implementing this. I think it might make sense to use password-hashes/pbkdf2/src/lib.rs Lines 110 to 123 in 48e3c53
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, looks good to me.
I'll give @newpavlov a few days to comment in case he can think of a better solution to the mutable aliasing problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got intrigued by the twitter thread, as @Bascule hoped, but I don't quite understand what this code is trying to do. :( More pointers would be helpful! I do see some problems with it as written, though.
I can try to write a short synopsis of how the Argon2 paper describes parallel operation of the algorithm (mostly summarizing sections 3.2 and 3.3, see also section 6.2 Implementing parallelism): https://www.password-hashing.net/argon2-specs.pdf The algorithm operates over a matrix of "blocks" consisting of:
Each lane is further subdivided into 𝑺 = 4 "slices" (in Argon2 terminology, and referred to as Segments of the same slice are computed in parallel and therefore cannot reference each other. So from a memory model perspective, what we'd really like is to mutably borrow the values of a particular slice, partition them into segments, and give each worker thread access to a particular segment. However, we also need to allow all of the worker threads to simultaneously borrow all of the other blocks which do not belong to the "slice" being operated on to reference as inputs. This is the tricky part: the Having just written all of that down (thanks for rubber ducking if nothing else), I think I have a better idea of how to model this problem safely in Rust: "slices" (in the Argon2 sense) should be the core level of granularity in which the working "memory" is organized. The main loop of the algorithm iterates over the slices. Provided I'm actually understanding this correctly, we can borrow one slice mutably at the time and the others immutably. The mutably borrowed slice can then be subdivided into a segment for each lane, given to the worker threads along with immutable references to all of the other slices. I think a big part of what's making this so tricky right now is the memory consists of a contiguous |
I think a next step which might be helpful in general is to extract a From there we can look at borrow splitting the backing buffer so |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also based on @nikomatsakis's comments I'm going to unapprove this for now
…nter in rayon closure
This should fix the UB as every thread now dereferences the pointer itself |
@smallglitch nice! I think that's a start. Do you want to mark the PR as ready for review? |
Sure, I wasn't sure if you'd be ok with an unsafe implementation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using unsafe
is fine for now. I can circle back on a safe implementation.
Thanks for extracting a Memory
type.
I opened #154 to track making the implementation safe |
…k-dev-macro digest: fix benchmark dev macro
Adds parallel processing for lanes
Closes #103
The parallelism is gated behind the feature
parallel
When the feature is activated, the
#![forbid(unsafe_code)]
gets downgraded to#![deny(unsafe_code)]
due to unsafe usage (here)The
#![no_std]
flag is being disabled as well