ant_protocol/storage/
scratchpad.rs1use super::ScratchpadAddress;
10use crate::error::{Error, Result};
11use crate::Bytes;
12use crate::NetworkAddress;
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!(self.verify_signature(), "Must be valid after being signed. This is a bug, please report it by opening an issue on our github");
138 }
139
140 pub fn verify_signature(&self) -> bool {
142 let signing_bytes = Self::bytes_for_signature(
143 self.address,
144 self.data_encoding,
145 &self.encrypted_data,
146 self.counter,
147 );
148 self.owner().verify(&self.signature, &signing_bytes)
149 }
150
151 pub fn encrypted_data(&self) -> &Bytes {
153 &self.encrypted_data
154 }
155
156 pub fn decrypt_data(&self, sk: &SecretKey) -> Result<Bytes> {
158 let cipher = Ciphertext::from_bytes(&self.encrypted_data)
159 .map_err(|_| Error::ScratchpadCipherTextFailed)?;
160 let bytes = sk
161 .decrypt(&cipher)
162 .ok_or(Error::ScratchpadCipherTextInvalid)?;
163 Ok(Bytes::from(bytes))
164 }
165
166 pub fn encrypted_data_hash(&self) -> XorName {
168 XorName::from_content(&self.encrypted_data)
169 }
170
171 pub fn owner(&self) -> &PublicKey {
173 self.address.owner()
174 }
175
176 pub fn address(&self) -> &ScratchpadAddress {
178 &self.address
179 }
180
181 pub fn network_address(&self) -> NetworkAddress {
183 NetworkAddress::ScratchpadAddress(self.address)
184 }
185
186 pub fn xorname(&self) -> XorName {
188 self.address.xorname()
189 }
190
191 pub fn payload_size(&self) -> usize {
193 self.encrypted_data.len()
194 }
195
196 pub fn size(&self) -> usize {
198 size_of::<Scratchpad>() + self.payload_size()
199 }
200
201 pub fn is_too_big(&self) -> bool {
203 self.size() > Self::MAX_SIZE
204 }
205}
206
207#[cfg(test)]
208mod tests {
209 use super::*;
210
211 #[test]
212 fn test_scratchpad_sig_and_update() {
213 let sk = SecretKey::random();
214 let raw_data = Bytes::from_static(b"data to be encrypted");
215 let mut scratchpad = Scratchpad::new(&sk, 42, &raw_data, 0);
216 assert!(scratchpad.verify_signature());
217 assert_eq!(scratchpad.counter(), 0);
218 assert_ne!(scratchpad.encrypted_data(), &raw_data);
219
220 let raw_data2 = Bytes::from_static(b"data to be encrypted v2");
221 scratchpad.update(&raw_data2, &sk);
222 assert!(scratchpad.verify_signature());
223 assert_eq!(scratchpad.counter(), 1);
224 assert_ne!(scratchpad.encrypted_data(), &raw_data);
225 assert_ne!(scratchpad.encrypted_data(), &raw_data2);
226 }
227
228 #[test]
229 fn test_scratchpad_encryption() {
230 let sk = SecretKey::random();
231 let raw_data = Bytes::from_static(b"data to be encrypted");
232 let scratchpad = Scratchpad::new(&sk, 42, &raw_data, 0);
233
234 let decrypted_data = scratchpad.decrypt_data(&sk).unwrap();
235 assert_eq!(decrypted_data, raw_data);
236 }
237}