pcg.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use rand::{CryptoRng, Error, RngCore};
  19. pub struct Pcg32 {
  20. state: u64,
  21. increment: u64,
  22. }
  23. impl Pcg32 {
  24. const MULTIPLIER: u64 = 6364136223846793005;
  25. const INCREMENT: u64 = 1442695040888963407;
  26. pub fn new(seed: u64) -> Self {
  27. let mut rng = Self { state: 0, increment: Self::INCREMENT | 1 };
  28. rng.state = rng.state.wrapping_add(seed);
  29. rng.state = rng.state.wrapping_mul(Self::MULTIPLIER).wrapping_add(rng.increment);
  30. rng
  31. }
  32. fn next_u32(&mut self) -> u32 {
  33. let old_state = self.state;
  34. self.state = old_state.wrapping_mul(Self::MULTIPLIER).wrapping_add(self.increment);
  35. let xorshifted = ((old_state >> 18) ^ old_state) >> 27;
  36. let rot = old_state >> 59;
  37. (xorshifted >> rot | xorshifted << ((!rot).wrapping_add(1) & 31)) as u32
  38. }
  39. }
  40. impl CryptoRng for Pcg32 {}
  41. impl RngCore for Pcg32 {
  42. fn next_u32(&mut self) -> u32 {
  43. self.next_u32()
  44. }
  45. fn next_u64(&mut self) -> u64 {
  46. (self.next_u32() as u64) << 32 | (self.next_u32() as u64)
  47. }
  48. fn fill_bytes(&mut self, dest: &mut [u8]) {
  49. let mut i = 0;
  50. while i + 4 <= dest.len() {
  51. let bytes = self.next_u32().to_le_bytes();
  52. dest[i..i + 4].copy_from_slice(&bytes);
  53. i += 4;
  54. }
  55. if i < dest.len() {
  56. let bytes = self.next_u32().to_le_bytes();
  57. for (j, dest_byte) in dest[i..].iter_mut().enumerate() {
  58. *dest_byte = bytes[j];
  59. }
  60. }
  61. }
  62. fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
  63. self.fill_bytes(dest);
  64. Ok(())
  65. }
  66. }
  67. #[cfg(test)]
  68. mod tests {
  69. use super::*;
  70. #[test]
  71. fn test_pcg() {
  72. const ITERS: usize = 10000;
  73. let mut rng0 = Pcg32::new(42);
  74. let mut rng1 = Pcg32::new(42);
  75. for i in 0..ITERS {
  76. let a = rng0.next_u32();
  77. let b = rng1.next_u32();
  78. assert!(a == b);
  79. let a = rng0.next_u64();
  80. let b = rng1.next_u64();
  81. assert!(a == b);
  82. let mut buf0 = vec![0u8; i];
  83. let mut buf1 = vec![0u8; i];
  84. rng0.fill_bytes(&mut buf0);
  85. rng1.fill_bytes(&mut buf1);
  86. assert!(buf0 == buf1);
  87. }
  88. }
  89. }