rns_core/resource/
proof.rs1use alloc::vec::Vec;
2
3use super::types::ResourceError;
4use crate::hash::full_hash;
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!(
94 validate_proof(&proof_data, &resource_hash, &expected),
95 Ok(true)
96 );
97 }
98
99 #[test]
100 fn test_validate_proof_wrong_hash_prefix_still_valid() {
101 let data = b"resource data";
103 let random = [0x11; 4];
104 let resource_hash = compute_resource_hash(data, &random);
105 let expected = compute_expected_proof(data, &resource_hash);
106 let wrong_hash = [0xFF; 32];
107 let proof_data = build_proof_data(&wrong_hash, &expected);
108 assert_eq!(
110 validate_proof(&proof_data, &resource_hash, &expected),
111 Ok(true)
112 );
113 }
114
115 #[test]
116 fn test_validate_proof_invalid_proof() {
117 let data = b"resource data";
118 let random = [0x11; 4];
119 let resource_hash = compute_resource_hash(data, &random);
120 let expected = compute_expected_proof(data, &resource_hash);
121 let wrong_proof = [0xFF; 32];
122 let proof_data = build_proof_data(&resource_hash, &wrong_proof);
123 assert_eq!(
124 validate_proof(&proof_data, &resource_hash, &expected),
125 Ok(false)
126 );
127 }
128
129 #[test]
130 fn test_validate_proof_wrong_length() {
131 let hash = [0x11; 32];
132 let proof = [0x22; 32];
133 assert!(validate_proof(&[0; 50], &hash, &proof).is_err());
134 assert!(validate_proof(&[], &hash, &proof).is_err());
135 }
136
137 #[test]
138 fn test_proof_uses_unencrypted_data() {
139 let random = [0xAA; 4];
141 let hash1 = compute_resource_hash(b"data1", &random);
142 let hash2 = compute_resource_hash(b"data2", &random);
143 assert_ne!(hash1, hash2);
144
145 let proof1 = compute_expected_proof(b"data1", &hash1);
146 let proof2 = compute_expected_proof(b"data2", &hash2);
147 assert_ne!(proof1, proof2);
148 }
149}