ps_ecc/polynomial/implementations/
hash.rs1use std::hash::{Hash, Hasher};
2
3use crate::Polynomial;
4
5impl Hash for Polynomial {
6 fn hash<H: Hasher>(&self, state: &mut H) {
7 self.degree.hash(state);
8 self.coefficients[..=self.degree as usize].hash(state);
9 }
10}
11
12#[cfg(test)]
13#[allow(clippy::expect_used)]
14mod tests {
15 use std::collections::hash_map::DefaultHasher;
16 use std::hash::{Hash, Hasher};
17
18 use crate::Polynomial;
19
20 fn hash_of<T: Hash>(value: &T) -> u64 {
21 let mut hasher = DefaultHasher::new();
22
23 value.hash(&mut hasher);
24 hasher.finish()
25 }
26
27 #[test]
28 fn equal_polynomials_same_hash() {
29 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid");
30 let b = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid");
31
32 assert_eq!(hash_of(&a), hash_of(&b));
33 }
34
35 #[test]
36 fn trailing_zeros_same_hash() {
37 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid");
38 let b = Polynomial::try_from(&[1u8, 2, 3, 0, 0][..]).expect("valid");
39
40 assert_eq!(a, b);
41 assert_eq!(hash_of(&a), hash_of(&b));
42 }
43
44 #[test]
45 fn different_polynomials_likely_different_hash() {
46 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid");
47 let b = Polynomial::try_from(&[1u8, 2, 4][..]).expect("valid");
48
49 assert_ne!(hash_of(&a), hash_of(&b));
51 }
52
53 #[test]
54 fn zero_polynomial_consistent_hash() {
55 let a = Polynomial::default();
56 let b = Polynomial::default();
57
58 assert_eq!(hash_of(&a), hash_of(&b));
59 }
60
61 #[test]
62 fn different_degrees_different_hash() {
63 let a = Polynomial::try_from(&[1u8][..]).expect("valid");
64 let b = Polynomial::try_from(&[1u8, 0, 1][..]).expect("valid");
65
66 assert_ne!(hash_of(&a), hash_of(&b));
67 }
68}