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(
20 Hash, Eq, PartialEq, PartialOrd, Ord, Clone, custom_debug::Debug, Serialize, Deserialize,
21)]
22pub struct Scratchpad {
23 address: ScratchpadAddress,
26 data_encoding: u64,
28 #[debug(skip)]
30 encrypted_data: Bytes,
31 counter: u64,
34 signature: Signature,
36}
37
38impl Scratchpad {
39 pub const MAX_SIZE: usize = 4 * 1024 * 1024;
41
42 pub fn new(
44 owner: &SecretKey,
45 data_encoding: u64,
46 unencrypted_data: &Bytes,
47 counter: u64,
48 ) -> Self {
49 let pk = owner.public_key();
50 let encrypted_data = Bytes::from(pk.encrypt(unencrypted_data).to_bytes());
51 let addr = ScratchpadAddress::new(pk);
52 let signature = owner.sign(Self::bytes_for_signature(
53 addr,
54 data_encoding,
55 &encrypted_data,
56 counter,
57 ));
58 Self {
59 address: addr,
60 encrypted_data,
61 data_encoding,
62 counter,
63 signature,
64 }
65 }
66
67 pub fn new_with_signature(
71 owner: PublicKey,
72 data_encoding: u64,
73 encrypted_data: Bytes,
74 counter: u64,
75 signature: Signature,
76 ) -> Self {
77 Self {
78 address: ScratchpadAddress::new(owner),
79 encrypted_data,
80 data_encoding,
81 counter,
82 signature,
83 }
84 }
85
86 pub fn bytes_for_signature(
88 address: ScratchpadAddress,
89 data_encoding: u64,
90 encrypted_data: &Bytes,
91 counter: u64,
92 ) -> Vec<u8> {
93 let mut bytes_to_sign = data_encoding.to_be_bytes().to_vec();
94 bytes_to_sign.extend(address.to_hex().as_bytes());
95 bytes_to_sign.extend(counter.to_be_bytes().to_vec());
96 bytes_to_sign.extend(encrypted_data.to_vec());
97 bytes_to_sign
98 }
99
100 pub fn counter(&self) -> u64 {
103 self.counter
104 }
105
106 pub fn data_encoding(&self) -> u64 {
108 self.data_encoding
109 }
110
111 pub fn update(&mut self, unencrypted_data: &Bytes, sk: &SecretKey) {
113 self.counter += 1;
114 let pk = self.owner();
115 let address = ScratchpadAddress::new(*pk);
116 self.encrypted_data = Bytes::from(pk.encrypt(unencrypted_data).to_bytes());
117
118 let bytes_to_sign = Self::bytes_for_signature(
119 address,
120 self.data_encoding,
121 &self.encrypted_data,
122 self.counter,
123 );
124 self.signature = sk.sign(&bytes_to_sign);
125 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");
126 }
127
128 pub fn verify_signature(&self) -> bool {
130 let signing_bytes = Self::bytes_for_signature(
131 self.address,
132 self.data_encoding,
133 &self.encrypted_data,
134 self.counter,
135 );
136 self.owner().verify(&self.signature, &signing_bytes)
137 }
138
139 pub fn encrypted_data(&self) -> &Bytes {
141 &self.encrypted_data
142 }
143
144 pub fn decrypt_data(&self, sk: &SecretKey) -> Result<Bytes> {
146 let cipher = Ciphertext::from_bytes(&self.encrypted_data)
147 .map_err(|_| Error::ScratchpadCipherTextFailed)?;
148 let bytes = sk
149 .decrypt(&cipher)
150 .ok_or(Error::ScratchpadCipherTextInvalid)?;
151 Ok(Bytes::from(bytes))
152 }
153
154 pub fn encrypted_data_hash(&self) -> XorName {
156 XorName::from_content(&self.encrypted_data)
157 }
158
159 pub fn owner(&self) -> &PublicKey {
161 self.address.owner()
162 }
163
164 pub fn address(&self) -> &ScratchpadAddress {
166 &self.address
167 }
168
169 pub fn network_address(&self) -> NetworkAddress {
171 NetworkAddress::ScratchpadAddress(self.address)
172 }
173
174 pub fn xorname(&self) -> XorName {
176 self.address.xorname()
177 }
178
179 pub fn payload_size(&self) -> usize {
181 self.encrypted_data.len()
182 }
183
184 pub fn size(&self) -> usize {
186 size_of::<Scratchpad>() + self.payload_size()
187 }
188
189 pub fn is_too_big(&self) -> bool {
191 self.size() > Self::MAX_SIZE
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use super::*;
198
199 #[test]
200 fn test_scratchpad_sig_and_update() {
201 let sk = SecretKey::random();
202 let raw_data = Bytes::from_static(b"data to be encrypted");
203 let mut scratchpad = Scratchpad::new(&sk, 42, &raw_data, 0);
204 assert!(scratchpad.verify_signature());
205 assert_eq!(scratchpad.counter(), 0);
206 assert_ne!(scratchpad.encrypted_data(), &raw_data);
207
208 let raw_data2 = Bytes::from_static(b"data to be encrypted v2");
209 scratchpad.update(&raw_data2, &sk);
210 assert!(scratchpad.verify_signature());
211 assert_eq!(scratchpad.counter(), 1);
212 assert_ne!(scratchpad.encrypted_data(), &raw_data);
213 assert_ne!(scratchpad.encrypted_data(), &raw_data2);
214 }
215
216 #[test]
217 fn test_scratchpad_encryption() {
218 let sk = SecretKey::random();
219 let raw_data = Bytes::from_static(b"data to be encrypted");
220 let scratchpad = Scratchpad::new(&sk, 42, &raw_data, 0);
221
222 let decrypted_data = scratchpad.decrypt_data(&sk).unwrap();
223 assert_eq!(decrypted_data, raw_data);
224 }
225}