prime.rs 1.2 KB

1234567891011121314151617181920212223242526272829303132333435
  1. use {crate::hashers::Hasher, serde::Serialize, sha3::Digest, slow_primes::is_prime_miller_rabin};
  2. #[derive(Clone, Default, Debug, Eq, PartialEq, Serialize)]
  3. pub struct PrimeHasher {}
  4. impl Hasher for PrimeHasher {
  5. // u128 in big endian bytes
  6. type Hash = [u8; 16];
  7. fn hashv(data: &[impl AsRef<[u8]>]) -> [u8; 16] {
  8. // Scan for primes generated by hashing the bytes starting from 0. We use a number like
  9. // this so once the prime is found we can directly compute the hash instead of scanning
  10. // the range again.
  11. let mut search = 0usize;
  12. loop {
  13. // Increment Search Counter.
  14. search += 1;
  15. // Hash Input.
  16. let mut hasher = sha3::Sha3_256::new();
  17. for d in data {
  18. hasher.update(d);
  19. }
  20. hasher.update(search.to_be_bytes());
  21. let hash_bytes: [u8; 32] = hasher.finalize().into();
  22. // Take only a u32 from the end, return if its prime.
  23. let prime = u32::from_be_bytes(hash_bytes[28..].try_into().unwrap()) | 1;
  24. if is_prime_miller_rabin(prime as u64) {
  25. return (prime as u128).to_be_bytes();
  26. }
  27. }
  28. }
  29. }