rns_core/resource/
proof.rs1use alloc::vec::Vec;
2
3use crate::hash::full_hash;
4use super::types::ResourceError;
5
6pub fn compute_resource_hash(unencrypted_data: &[u8], random_hash: &[u8]) -> [u8; 32] {
10 let mut input = Vec::with_capacity(unencrypted_data.len() + random_hash.len());
11 input.extend_from_slice(unencrypted_data);
12 input.extend_from_slice(random_hash);
13 full_hash(&input)
14}
15
16pub fn compute_expected_proof(unencrypted_data: &[u8], resource_hash: &[u8; 32]) -> [u8; 32] {
19 let mut input = Vec::with_capacity(unencrypted_data.len() + 32);
20 input.extend_from_slice(unencrypted_data);
21 input.extend_from_slice(resource_hash);
22 full_hash(&input)
23}
24
25pub fn build_proof_data(resource_hash: &[u8; 32], proof: &[u8; 32]) -> Vec<u8> {
27 let mut data = Vec::with_capacity(64);
28 data.extend_from_slice(resource_hash);
29 data.extend_from_slice(proof);
30 data
31}
32
33pub fn validate_proof(
39 proof_data: &[u8],
40 _expected_resource_hash: &[u8; 32],
41 expected_proof: &[u8; 32],
42) -> Result<bool, ResourceError> {
43 if proof_data.len() != 64 {
44 return Err(ResourceError::InvalidProof);
45 }
46 let recv_proof = &proof_data[32..64];
47 Ok(recv_proof == expected_proof.as_slice())
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn test_compute_resource_hash() {
56 let data = b"test resource data";
57 let random = [0xAA, 0xBB, 0xCC, 0xDD];
58 let hash = compute_resource_hash(data, &random);
59 assert_eq!(hash.len(), 32);
60
61 let hash2 = compute_resource_hash(data, &random);
63 assert_eq!(hash, hash2);
64 }
65
66 #[test]
67 fn test_compute_expected_proof() {
68 let data = b"test resource data";
69 let random = [0xAA, 0xBB, 0xCC, 0xDD];
70 let resource_hash = compute_resource_hash(data, &random);
71 let proof = compute_expected_proof(data, &resource_hash);
72 assert_eq!(proof.len(), 32);
73 assert_ne!(proof, resource_hash); }
75
76 #[test]
77 fn test_build_proof_data() {
78 let hash = [0x11u8; 32];
79 let proof = [0x22u8; 32];
80 let data = build_proof_data(&hash, &proof);
81 assert_eq!(data.len(), 64);
82 assert_eq!(&data[..32], &hash);
83 assert_eq!(&data[32..], &proof);
84 }
85
86 #[test]
87 fn test_validate_proof_valid() {
88 let data = b"resource data here";
89 let random = [0x11, 0x22, 0x33, 0x44];
90 let resource_hash = compute_resource_hash(data, &random);
91 let expected = compute_expected_proof(data, &resource_hash);
92 let proof_data = build_proof_data(&resource_hash, &expected);
93 assert_eq!(validate_proof(&proof_data, &resource_hash, &expected), Ok(true));
94 }
95
96 #[test]
97 fn test_validate_proof_wrong_hash_prefix_still_valid() {
98 let data = b"resource data";
100 let random = [0x11; 4];
101 let resource_hash = compute_resource_hash(data, &random);
102 let expected = compute_expected_proof(data, &resource_hash);
103 let wrong_hash = [0xFF; 32];
104 let proof_data = build_proof_data(&wrong_hash, &expected);
105 assert_eq!(validate_proof(&proof_data, &resource_hash, &expected), Ok(true));
107 }
108
109 #[test]
110 fn test_validate_proof_invalid_proof() {
111 let data = b"resource data";
112 let random = [0x11; 4];
113 let resource_hash = compute_resource_hash(data, &random);
114 let expected = compute_expected_proof(data, &resource_hash);
115 let wrong_proof = [0xFF; 32];
116 let proof_data = build_proof_data(&resource_hash, &wrong_proof);
117 assert_eq!(validate_proof(&proof_data, &resource_hash, &expected), Ok(false));
118 }
119
120 #[test]
121 fn test_validate_proof_wrong_length() {
122 let hash = [0x11; 32];
123 let proof = [0x22; 32];
124 assert!(validate_proof(&[0; 50], &hash, &proof).is_err());
125 assert!(validate_proof(&[], &hash, &proof).is_err());
126 }
127
128 #[test]
129 fn test_proof_uses_unencrypted_data() {
130 let random = [0xAA; 4];
132 let hash1 = compute_resource_hash(b"data1", &random);
133 let hash2 = compute_resource_hash(b"data2", &random);
134 assert_ne!(hash1, hash2);
135
136 let proof1 = compute_expected_proof(b"data1", &hash1);
137 let proof2 = compute_expected_proof(b"data2", &hash2);
138 assert_ne!(proof1, proof2);
139 }
140}