-
Notifications
You must be signed in to change notification settings - Fork 432
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
Cherry-pick changes to PRNG algorithms #209
Conversation
Edit: fixed for Rust 1.15 |
I have read over the changes, and it looks like a lot of work backporting! It looks good, there is nothing I could comment on. The change to make |
Yes, I deliberately missed out |
Rebased (first commit moving |
Breaking changes (see also here):
Not sure at the moment whether to try to work around the above (not so easy) or make this wait until 0.5. |
Ok, I reverted all the above breaking changes (except to The commits affecting |
src/lib.rs
Outdated
fn next_u64(&mut self) -> u64 { | ||
((self.next_u32() as u64) << 32) | (self.next_u32() as u64) | ||
impls::next_u64_via_u32(self) |
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.
This is also a breaking change (was BE, or possibly undefined order)
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.
No, it turns out the old code also produced LE values (for me at least).
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.
Hmm, having that as a breaking change does not make me happy.
I double-checked your results, and if I add the test on the master branch it fails...
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.
Thanks for picking that up. I forgot IsaacRng
already has it's own impl of next_u64
! Now I get BE results from the old code too. Ok, will revert. Does this apply to fill_bytes
too?
Actually, this is more complicated: the |
Are you sure |
Well, there was change in output (I tried running the new The problem here is that these changes affect output that was not previously tested, and that we want to change anyway (standardise to LE). I don't want to write new tests to confirm we didn't break output that was untested before and will soon be obsolete. So unless someone else does that, I think I'll just merge all breaking changes except for the removal of default implementations in |
I was asking more because I was careful to preserve the order of
Seems like a good plan to me. As you say we want those changes in the end, so why go through all the hoops just to remain in the 0.4.* version. I am not sure what you want to wait for to remove the default implementations in |
This removes the unsafe blocks from the main isaac and isaac64 routines. Some macro's are replaced by functions. Over time the implementation of ISAAC and ISAAC-64 have diverged a bit, now they are as similar as possible (for easier comparison). The code is tested against the previous implementation, and the reference implementation. IsaacRng now does 34% better in the benchmark. [Cherry-picked from 4747665]
for next_u64 and fill_bytes This is based on dd1241a but heavily modified
[Cherry-picked from 14d0561]
Cherry-picked from adcd8e5 [by Paul Dicker, 19th October] I have implemented it as a function instead of a trait, as that makes it easy to add it to every RNG ont at a time. I split the `init` function in two instead of the current version that uses a bool to select between two paths. This makes it more clear how the seed is used. The current `mix` macro has to be defined in the function, and would have to be duplicated. Therefore I converted it to a seperate function. I precalculated the values a...h, but am not sure this is a good idea. It makes the resulting code smaller, and gives a small performance win. Because it are 'magic' values anyway, I thought why not?
[Cherry-picked from 130b64c]
So the internal state is never exposed (may be security-sensitive) [Cherry-picked from e513aaa]
…mpls [Cherry-picked from ae365ef]
This also replaces `core::num::Wrapping` with a few `wrapping_add`'s. There were about 30 conversions to and from `Wrapping`, while there are only 9 wrapping operations. Because `fill_via_u32_chunks` expects a `[u32]`, converting away was just easier. [Cherry-picked from d7b014c]
Also uses a different solution to index without bounds checking, to recover a very little bit of lost performance. [Cherry-picked from f92a347]
[Cherry-picked from 707c3e1]
[Cherry-picked from 5f4bedf]
Restore default implementations of next_u64 and fill_bytes Restore new_unseeded functions (as wrappers)
Updated (adjusted the "revert breaking changes" commit and squashed a couple of commits together to simplify). Due to breaking changes, this will land in 0.5. This means that breaking changes are those above minus the removal of default implementations and of |
🎉 |
Notable changes:
Rng::next_u64
andRng::fill_bytes
no longer have default implementationsimpls
module added (private; the idea is that this gets exported asrand_core::impls
later)Note that this is based on
core
(PR #208) which accounts for the changes to Cargo.toml and the README.Also note: yes, I merged these 17 commits by hand (ugh) and ran the tests for each. Reviewing in detail from this PR will be horrible; it may be easier to review the original commits if you want to do that. But everything has already been well reviewed by @pitdicker and myself and there are a bunch of tests, so I'm not too worried.