ant_protocol/storage/
scratchpad.rs1use super::ScratchpadAddress;
10use crate::Bytes;
11use crate::NetworkAddress;
12use crate::error::{Error, Result};
13use bls::{Ciphertext, PublicKey, SecretKey, Signature};
14use serde::{Deserialize, Serialize};
15
16use xor_name::XorName;
17
18#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Serialize, Deserialize)]
20pub struct Scratchpad {
21 address: ScratchpadAddress,
24 data_encoding: u64,
26 encrypted_data: Bytes,
28 counter: u64,
31 signature: Signature,
33}
34
35impl std::fmt::Debug for Scratchpad {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 f.debug_struct("Scratchpad")
38 .field("address", &self.address)
39 .field("data_encoding", &self.data_encoding)
40 .field(
41 "encrypted_data",
42 &format!("({} bytes of encrypted data)", self.encrypted_data.len()),
43 )
44 .field("counter", &self.counter)
45 .field("signature", &hex::encode(self.signature.to_bytes()))
46 .finish()
47 }
48}
49
50impl Scratchpad {
51 pub const MAX_SIZE: usize = 4 * 1024 * 1024;
53
54 pub fn new(
56 owner: &SecretKey,
57 data_encoding: u64,
58 unencrypted_data: &Bytes,
59 counter: u64,
60 ) -> Self {
61 let pk = owner.public_key();
62 let encrypted_data = Bytes::from(pk.encrypt(unencrypted_data).to_bytes());
63 let addr = ScratchpadAddress::new(pk);
64 let signature = owner.sign(Self::bytes_for_signature(
65 addr,
66 data_encoding,
67 &encrypted_data,
68 counter,
69 ));
70 Self {
71 address: addr,
72 encrypted_data,
73 data_encoding,
74 counter,
75 signature,
76 }
77 }
78
79 pub fn new_with_signature(
83 owner: PublicKey,
84 data_encoding: u64,
85 encrypted_data: Bytes,
86 counter: u64,
87 signature: Signature,
88 ) -> Self {
89 Self {
90 address: ScratchpadAddress::new(owner),
91 encrypted_data,
92 data_encoding,
93 counter,
94 signature,
95 }
96 }
97
98 pub fn bytes_for_signature(
100 address: ScratchpadAddress,
101 data_encoding: u64,
102 encrypted_data: &Bytes,
103 counter: u64,
104 ) -> Vec<u8> {
105 let mut bytes_to_sign = data_encoding.to_be_bytes().to_vec();
106 bytes_to_sign.extend(address.to_hex().as_bytes());
107 bytes_to_sign.extend(counter.to_be_bytes().to_vec());
108 bytes_to_sign.extend(encrypted_data.to_vec());
109 bytes_to_sign
110 }
111
112 pub fn counter(&self) -> u64 {
115 self.counter
116 }
117
118 pub fn data_encoding(&self) -> u64 {
120 self.data_encoding
121 }
122
123 pub fn update(&mut self, unencrypted_data: &Bytes, sk: &SecretKey) {
125 self.counter += 1;
126 let pk = self.owner();
127 let address = ScratchpadAddress::new(*pk);
128 self.encrypted_data = Bytes::from(pk.encrypt(unencrypted_data).to_bytes());
129
130 let bytes_to_sign = Self::bytes_for_signature(
131 address,
132 self.data_encoding,
133 &self.encrypted_data,
134 self.counter,
135 );
136 self.signature = sk.sign(&bytes_to_sign);
137 debug_assert!(
138 self.verify_signature(),
139 "Must be valid after being signed. This is a bug, please report it by opening an issue on our github"
140 );
141 }
142
143 pub fn verify_signature(&self) -> bool {
145 let signing_bytes = Self::bytes_for_signature(
146 self.address,
147 self.data_encoding,
148 &self.encrypted_data,
149 self.counter,
150 );
151 self.owner().verify(&self.signature, &signing_bytes)
152 }
153
154 pub fn encrypted_data(&self) -> &Bytes {
156 &self.encrypted_data
157 }
158
159 pub fn decrypt_data(&self, sk: &SecretKey) -> Result<Bytes> {
161 let cipher = Ciphertext::from_bytes(&self.encrypted_data)
162 .map_err(|_| Error::ScratchpadCipherTextFailed)?;
163 let bytes = sk
164 .decrypt(&cipher)
165 .ok_or(Error::ScratchpadCipherTextInvalid)?;
166 Ok(Bytes::from(bytes))
167 }
168
169 pub fn encrypted_data_hash(&self) -> XorName {
171 XorName::from_content(&self.encrypted_data)
172 }
173
174 pub fn owner(&self) -> &PublicKey {
176 self.address.owner()
177 }
178
179 pub fn address(&self) -> &ScratchpadAddress {
181 &self.address
182 }
183
184 pub fn network_address(&self) -> NetworkAddress {
186 NetworkAddress::ScratchpadAddress(self.address)
187 }
188
189 pub fn xorname(&self) -> XorName {
191 self.address.xorname()
192 }
193
194 pub fn payload_size(&self) -> usize {
196 self.encrypted_data.len()
197 }
198
199 pub fn size(&self) -> usize {
201 size_of::<Scratchpad>() + self.payload_size()
202 }
203
204 pub fn is_too_big(&self) -> bool {
206 self.size() > Self::MAX_SIZE
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213
214 #[test]
215 fn test_scratchpad_sig_and_update() {
216 let sk = SecretKey::random();
217 let raw_data = Bytes::from_static(b"data to be encrypted");
218 let mut scratchpad = Scratchpad::new(&sk, 42, &raw_data, 0);
219 assert!(scratchpad.verify_signature());
220 assert_eq!(scratchpad.counter(), 0);
221 assert_ne!(scratchpad.encrypted_data(), &raw_data);
222
223 let raw_data2 = Bytes::from_static(b"data to be encrypted v2");
224 scratchpad.update(&raw_data2, &sk);
225 assert!(scratchpad.verify_signature());
226 assert_eq!(scratchpad.counter(), 1);
227 assert_ne!(scratchpad.encrypted_data(), &raw_data);
228 assert_ne!(scratchpad.encrypted_data(), &raw_data2);
229 }
230
231 #[test]
232 fn test_scratchpad_encryption() {
233 let sk = SecretKey::random();
234 let raw_data = Bytes::from_static(b"data to be encrypted");
235 let scratchpad = Scratchpad::new(&sk, 42, &raw_data, 0);
236
237 let decrypted_data = scratchpad.decrypt_data(&sk).unwrap();
238 assert_eq!(decrypted_data, raw_data);
239 }
240}