1use std::{
20 ops::{Deref, DerefMut},
21 sync::Arc,
22};
23
24use object_rainbow::{
25 Address, ByteNode, Error, ExtraFor, FailFuture, Fetch, FetchBytes, Hash, ListHashes, Node,
26 Parse, ParseInline, ParseSliceExtra, PointInput, PointVisitor, Resolve, Singular,
27 SingularFetch, Tagged, ToOutput, TopoVec, Topological, Traversible,
28 addressed::ExtractResolve,
29 derive_for_wrapped,
30 fn_fetch::{FnFetch, closure_fetch},
31 length_prefixed::LpVec,
32 map_extra::MappedExtra,
33 tuple_extra::Extra0,
34};
35use object_rainbow_point::{Extras, Point};
36
37pub mod tuple_key;
38
39#[derive_for_wrapped]
40pub trait Key: 'static + Sized + Send + Sync + Clone + PartialEq + Eq {
41 type Error: 'static + Send + Sync + std::error::Error;
42 fn encrypt(&self, data: &[u8]) -> Vec<u8>;
43 fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error>;
44 fn mangle_prefix(&self) -> Vec<u8> {
45 self.encrypt(b"this encrypted constant is followed by an unencrypted inner hash")
46 }
47 fn encrypt_output(&self, object: impl ToOutput) -> Vec<u8> {
48 self.encrypt(&object.vec())
49 }
50}
51
52#[derive(ToOutput, Parse, ParseInline, Clone)]
53struct RawResolve<K> {
54 key: Extras<K>,
55 resolve: Arc<dyn Resolve>,
56 addresses: Arc<LpVec<Address>>,
57}
58
59impl<K> RawResolve<K> {
60 fn translate(&self, address: Address) -> object_rainbow::Result<Address> {
61 self.addresses
62 .get(address.index)
63 .copied()
64 .ok_or(Error::AddressOutOfBounds)
65 }
66}
67
68fn side_parse<K: Key>(
69 key: &K,
70 data: &[u8],
71 resolve: &Arc<dyn Resolve>,
72) -> object_rainbow::Result<(InnerHeader<K>, Vec<u8>)> {
73 let data = key
74 .decrypt(data)
75 .map_err(object_rainbow::Error::consistency)?;
76 <(InnerHeader<K>, Vec<u8>) as ParseSliceExtra<K>>::parse_slice_extra(&data, resolve, key)
77}
78
79impl<K: Key> Resolve for RawResolve<K> {
80 fn resolve<'a>(
81 &'a self,
82 address: Address,
83 _: &'a Arc<dyn Resolve>,
84 ) -> FailFuture<'a, ByteNode> {
85 Box::pin(async move {
86 let address = self.translate(address)?;
87 let (data, resolve) = self.resolve.resolve(address, &self.resolve).await?;
88 let (InnerHeader { resolve, .. }, data) = side_parse(&self.key.0, &data, &resolve)?;
89 let resolve = Arc::new(resolve) as _;
90 Ok((data, resolve))
91 })
92 }
93
94 fn resolve_data(&'_ self, address: Address) -> FailFuture<'_, Vec<u8>> {
95 Box::pin(async move {
96 let address = self.translate(address)?;
97 let (data, resolve) = self.resolve.resolve(address, &self.resolve).await?;
98 let (_, data) = side_parse(&self.key.0, &data, &resolve)?;
99 Ok(data)
100 })
101 }
102
103 fn try_resolve_local(
104 &self,
105 address: Address,
106 _: &Arc<dyn Resolve>,
107 ) -> object_rainbow::Result<Option<ByteNode>> {
108 let address = self.translate(address)?;
109 let Some((data, resolve)) = self.resolve.try_resolve_local(address, &self.resolve)? else {
110 return Ok(None);
111 };
112 let (InnerHeader { resolve, .. }, data) = side_parse(&self.key.0, &data, &resolve)?;
113 let resolve = Arc::new(resolve) as _;
114 Ok(Some((data, resolve)))
115 }
116}
117
118#[derive(Parse, ParseInline)]
119struct InnerHeader<K> {
120 tags: Hash,
121 resolve: RawResolve<K>,
122}
123
124impl<K: Key> InnerHeader<K> {
125 fn with<T: Topological + Tagged>(self, decrypted: T) -> object_rainbow::Result<Inner<K, T>> {
126 if self.tags != T::HASH {
127 return Err(object_rainbow::error_consistency!("tags mismatch"));
128 }
129 let mut topology = TopoVec::new();
130 let mut v = RawVisit {
131 at: 0,
132 resolve: &self.resolve,
133 visitor: &mut topology,
134 };
135 decrypted.traverse(&mut v);
136 v.done()?;
137 let topology = Arc::new(LpVec(topology));
138 let decrypted = Arc::new(decrypted);
139 Ok(Inner {
140 tags: self.tags,
141 key: self.resolve.key,
142 topology,
143 decrypted,
144 })
145 }
146}
147
148#[derive(ToOutput)]
149struct Inner<K, T> {
150 tags: Hash,
151 key: Extras<K>,
152 topology: Arc<LpVec<Arc<dyn Singular>>>,
153 decrypted: Arc<T>,
154}
155
156struct RawVisit<'a, K, V> {
157 at: usize,
158 resolve: &'a RawResolve<K>,
159 visitor: &'a mut V,
160}
161
162impl<'a, K, V> RawVisit<'a, K, V> {
163 fn done(self) -> object_rainbow::Result<()> {
164 if self.at != self.resolve.addresses.len() {
165 Err(Error::AddressOutOfBounds)
166 } else {
167 Ok(())
168 }
169 }
170}
171
172#[derive(Clone)]
173struct RawFetch<K, D> {
174 key: K,
175 resolve: Arc<dyn Resolve>,
176 address: Address,
177 decrypted: D,
178}
179
180impl<K, D> FetchBytes for RawFetch<K, D> {
181 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
182 self.resolve.resolve(self.address, &self.resolve)
183 }
184
185 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
186 self.resolve.resolve_data(self.address)
187 }
188
189 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
190 self.resolve.try_resolve_local(self.address, &self.resolve)
191 }
192}
193
194impl<K: Key, D: Fetch<T: Topological + Tagged>> Fetch for RawFetch<K, D> {
195 type T = Encrypted<K, D::T>;
196
197 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
198 Box::pin(async move {
199 let (encrypted, resolve) = self.resolve.resolve(self.address, &self.resolve).await?;
200 let (header, _) = side_parse(&self.key, &encrypted, &resolve)?;
201 let decrypted = self.decrypted.fetch().await?;
202 let inner = header.with(decrypted)?;
203 Ok(Encrypted { inner })
204 })
205 }
206
207 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
208 let Some((encrypted, resolve)) = self
209 .resolve
210 .try_resolve_local(self.address, &self.resolve)?
211 else {
212 return Ok(None);
213 };
214 let (header, _) = side_parse(&self.key, &encrypted, &resolve)?;
215 let Some((decrypted, _)) = self.decrypted.try_fetch_local()? else {
216 return Ok(None);
217 };
218 let inner = header.with(decrypted)?;
219 Ok(Some((Encrypted { inner }, resolve)))
220 }
221}
222
223impl<K: Send + Sync, D: Send + Sync> Singular for RawFetch<K, D> {
224 fn hash(&self) -> Hash {
225 self.address.hash
226 }
227}
228
229impl<'a, K: Key, V: PointVisitor> PointVisitor for RawVisit<'a, K, V> {
230 fn visit(&mut self, point: &(impl 'static + SingularFetch<T: Traversible> + Clone)) {
231 let at = self.at;
232 self.at += 1;
233 if let Some(address) = self.resolve.addresses.get(at).copied() {
234 let key = self.resolve.key.0.clone();
235 let resolve = self.resolve.resolve.clone();
236 let decrypted = point.clone();
237 self.visitor.visit(&RawFetch {
238 key,
239 resolve,
240 address,
241 decrypted,
242 });
243 }
244 }
245}
246
247impl<
248 K: Key,
249 T: Topological + Tagged,
250 Extra: 'static + Send + Sync + Clone + ExtraFor<T>,
251 I: PointInput<Extra = (K, Extra)>,
252> Parse<I> for Inner<K, T>
253{
254 fn parse(mut input: I) -> object_rainbow::Result<Self> {
255 let header = input
256 .parse_inline::<MappedExtra<InnerHeader<K>, Extra0>>()?
257 .1;
258 let extra = input.extra().1.clone();
259 let decrypted = extra.parse(
260 &input.parse_all()?,
261 &(Arc::new(header.resolve.clone()) as _),
262 )?;
263 if decrypted.point_count() != header.resolve.addresses.len() {
264 return Err(object_rainbow::error_consistency!(
265 "too many addresses in the header",
266 ));
267 }
268 header.with(decrypted)
269 }
270}
271
272impl<K: Clone, T> Clone for Inner<K, T> {
273 fn clone(&self) -> Self {
274 Self {
275 tags: self.tags,
276 key: self.key.clone(),
277 topology: self.topology.clone(),
278 decrypted: self.decrypted.clone(),
279 }
280 }
281}
282
283#[derive(Clone)]
284struct InnerFetch<K, D> {
285 key: K,
286 encrypted: Arc<dyn Singular>,
287 decrypted: D,
288}
289
290impl<K, D> FetchBytes for InnerFetch<K, D> {
291 fn fetch_bytes(&'_ self) -> FailFuture<'_, ByteNode> {
292 self.encrypted.fetch_bytes()
293 }
294
295 fn fetch_data(&'_ self) -> FailFuture<'_, Vec<u8>> {
296 self.encrypted.fetch_data()
297 }
298
299 fn fetch_bytes_local(&self) -> object_rainbow::Result<Option<ByteNode>> {
300 self.encrypted.fetch_bytes_local()
301 }
302
303 fn fetch_data_local(&self) -> Option<Vec<u8>> {
304 self.encrypted.fetch_data_local()
305 }
306}
307
308impl<K: Key, D: Fetch<T: Topological + Tagged>> Fetch for InnerFetch<K, D> {
309 type T = Encrypted<K, D::T>;
310
311 fn fetch(&'_ self) -> FailFuture<'_, Self::T> {
312 Box::pin(async move {
313 let (encrypted, resolve) = self.encrypted.fetch_bytes().await?;
314 let (header, _) = side_parse(&self.key, &encrypted, &resolve)?;
315 let decrypted = self.decrypted.fetch().await?;
316 let inner = header.with(decrypted)?;
317 Ok(Encrypted { inner })
318 })
319 }
320
321 fn try_fetch_local(&self) -> object_rainbow::Result<Option<Node<Self::T>>> {
322 let Some((encrypted, resolve)) = self.encrypted.fetch_bytes_local()? else {
323 return Ok(None);
324 };
325 let (header, _) = side_parse(&self.key, &encrypted, &resolve)?;
326 let Some((decrypted, _)) = self.decrypted.try_fetch_local()? else {
327 return Ok(None);
328 };
329 let inner = header.with(decrypted)?;
330 Ok(Some((Encrypted { inner }, resolve)))
331 }
332}
333
334impl<K: Send + Sync, D: Send + Sync> Singular for InnerFetch<K, D> {
335 fn hash(&self) -> Hash {
336 self.encrypted.hash()
337 }
338}
339
340struct IterateResolution<'a, 'r, K, V> {
341 key: &'a K,
342 topology: &'r mut std::slice::Iter<'a, Arc<dyn Singular>>,
343 visitor: &'a mut V,
344}
345
346impl<'a, K: Key, V: PointVisitor> PointVisitor for IterateResolution<'a, '_, K, V> {
347 fn visit(&mut self, decrypted: &(impl 'static + SingularFetch<T: Traversible> + Clone)) {
348 let decrypted = decrypted.clone();
349 let encrypted = self.topology.next().expect("length mismatch").clone();
350 let point = Point::from_singular(InnerFetch {
351 key: self.key.clone(),
352 decrypted,
353 encrypted,
354 });
355 self.visitor.visit(&point);
356 }
357}
358
359impl<K, T> ListHashes for Inner<K, T> {
360 fn list_hashes(&self, f: &mut impl FnMut(Hash)) {
361 self.topology.list_hashes(f);
362 }
363
364 fn topology_hash(&self) -> Hash {
365 self.topology.0.data_hash()
366 }
367
368 fn point_count(&self) -> usize {
369 self.topology.len()
370 }
371}
372
373impl<K: Key, T: Topological> Topological for Inner<K, T> {
374 fn traverse(&self, visitor: &mut impl PointVisitor) {
375 let topology = &mut self.topology.iter();
376 self.decrypted.traverse(&mut IterateResolution {
377 key: &self.key.0,
378 topology,
379 visitor,
380 });
381 assert!(topology.next().is_none());
382 }
383
384 fn topology(&self) -> TopoVec {
385 self.topology.0.clone()
386 }
387}
388
389pub struct Encrypted<K, T> {
390 inner: Inner<K, T>,
391}
392
393impl<K, T: Clone> Encrypted<K, T> {
394 pub fn into_inner(self) -> T {
395 Arc::unwrap_or_clone(self.inner.decrypted)
396 }
397}
398
399impl<K, T> Deref for Encrypted<K, T> {
400 type Target = T;
401
402 fn deref(&self) -> &Self::Target {
403 self.inner.decrypted.as_ref()
404 }
405}
406
407impl<K: Clone, T> Clone for Encrypted<K, T> {
408 fn clone(&self) -> Self {
409 Self {
410 inner: self.inner.clone(),
411 }
412 }
413}
414
415impl<K, T> ListHashes for Encrypted<K, T> {
416 fn list_hashes(&self, f: &mut impl FnMut(Hash)) {
417 self.inner.list_hashes(f);
418 }
419
420 fn topology_hash(&self) -> Hash {
421 self.inner.topology_hash()
422 }
423
424 fn point_count(&self) -> usize {
425 self.inner.point_count()
426 }
427}
428
429impl<K: Key, T: Topological> Topological for Encrypted<K, T> {
430 fn traverse(&self, visitor: &mut impl PointVisitor) {
431 self.inner.traverse(visitor);
432 }
433}
434
435impl<K: Key, T: ToOutput> ToOutput for Encrypted<K, T> {
436 fn to_output(&self, output: &mut impl object_rainbow::Output) {
437 if output.is_mangling() {
438 output.write(&*self.inner.key.mangle_prefix().data_hash());
439 output.write(&*self.inner.decrypted.data_hash());
440 }
441 if output.is_real() {
442 output.write(&self.inner.key.encrypt_output(&self.inner));
443 }
444 }
445}
446
447trait EncryptedExtra<K>: 'static + Send + Sync + Clone {
448 type Extra: 'static + Send + Sync + Clone;
449 fn parts(&self) -> (K, Self::Extra);
450}
451
452impl<K: 'static + Send + Sync + Clone, Extra: 'static + Send + Sync + Clone> EncryptedExtra<K>
453 for (K, Extra)
454{
455 type Extra = Extra;
456
457 fn parts(&self) -> (K, Self::Extra) {
458 self.clone()
459 }
460}
461
462impl<K: 'static + Send + Sync + Clone> EncryptedExtra<K> for K {
463 type Extra = ();
464
465 fn parts(&self) -> (K, Self::Extra) {
466 (self.clone(), ())
467 }
468}
469
470impl<
471 K: Key,
472 T: Topological + Tagged,
473 Extra: 'static + Send + Sync + Clone + ExtraFor<T>,
474 I: PointInput<Extra: EncryptedExtra<K, Extra = Extra>>,
475> Parse<I> for Encrypted<K, T>
476{
477 fn parse(input: I) -> object_rainbow::Result<Self> {
478 let with_key = input.extra().parts();
479 let resolve = input.resolve().clone();
480 let source = with_key
481 .0
482 .decrypt(&input.parse_all()?)
483 .map_err(object_rainbow::Error::consistency)?;
484 let inner = Inner::<K, T>::parse_slice_extra(&source, &resolve, &with_key)?;
485 Ok(Self { inner })
486 }
487}
488
489impl<K, T> Tagged for Encrypted<K, T> {}
490
491type Extracted =
492 Vec<std::pin::Pin<Box<dyn Future<Output = Result<Arc<dyn Singular>, Error>> + Send + 'static>>>;
493
494struct ExtractResolution<'a, K> {
495 extracted: &'a mut Extracted,
496 key: &'a K,
497}
498
499impl<K: Key> PointVisitor for ExtractResolution<'_, K> {
500 fn visit(&mut self, decrypted: &(impl 'static + SingularFetch<T: Traversible> + Clone)) {
501 let decrypted = decrypted.clone();
502 let key = self.key.clone();
503 self.extracted.push(Box::pin(async move {
504 Ok(Arc::new(encrypt_point(key, decrypted).await?) as _)
505 }));
506 }
507}
508
509pub async fn encrypt_point<K: Key, T: Traversible>(
510 key: K,
511 decrypted: impl 'static + SingularFetch<T = T>,
512) -> object_rainbow::Result<Point<Encrypted<K, T>>> {
513 if let Some((address, resolve)) = decrypted.extract_resolve::<RawResolve<K>>()
514 && resolve.key.0 == key
515 {
516 let address = resolve.translate(*address)?;
517 let point = Point::from_singular(RawFetch {
518 key,
519 resolve: resolve.resolve.clone(),
520 address,
521 decrypted,
522 });
523 return Ok(point);
524 };
525 let encrypted = encrypt(key.clone(), decrypted.fetch().await?).await?;
526 let topology = encrypted.inner.topology.clone();
527 let point = Point::from_alternate_source(
528 &encrypted,
529 FnFetch::new(closure_fetch(
530 (key, decrypted, topology),
531 async |(key, decrypted, topology)| {
532 let decrypted = decrypted.fetch().await?;
533 let topology = topology.clone();
534 let key = key.clone();
535 Ok(Encrypted::from_topology(key, topology, decrypted))
536 },
537 )),
538 );
539 Ok(point)
540}
541
542pub async fn encrypt<K: Key, T: Traversible>(
543 key: K,
544 decrypted: T,
545) -> object_rainbow::Result<Encrypted<K, T>> {
546 let mut futures = Vec::with_capacity(decrypted.point_count());
547 decrypted.traverse(&mut ExtractResolution {
548 extracted: &mut futures,
549 key: &key,
550 });
551 let topology = futures_util::future::try_join_all(futures).await?;
552 let topology = Arc::new(LpVec(topology));
553 Ok(Encrypted::from_topology(key, topology, decrypted))
554}
555
556impl<K: Key, T: Traversible> Encrypted<K, T> {
557 fn from_topology(key: K, topology: Arc<LpVec<Arc<dyn Singular>>>, decrypted: T) -> Self {
558 let decrypted = Arc::new(decrypted);
559 let inner = Inner {
560 tags: T::HASH,
561 key: Extras(key),
562 topology,
563 decrypted,
564 };
565 Self { inner }
566 }
567}
568
569impl<K: Key, T: Traversible + Clone> Encrypted<K, T> {
570 pub fn as_mut(&mut self) -> EncryptedMut<'_, K, T> {
571 let object = self.inner.decrypted.as_ref().clone();
572 EncryptedMut {
573 encrypted: self,
574 object,
575 }
576 }
577}
578
579pub struct EncryptedMut<'a, K, T> {
580 encrypted: &'a mut Encrypted<K, T>,
581 object: T,
582}
583
584impl<K, T> Deref for EncryptedMut<'_, K, T> {
585 type Target = T;
586
587 fn deref(&self) -> &Self::Target {
588 &self.object
589 }
590}
591
592impl<K, T> DerefMut for EncryptedMut<'_, K, T> {
593 fn deref_mut(&mut self) -> &mut Self::Target {
594 &mut self.object
595 }
596}
597
598impl<'a, K: Key, T: Traversible> EncryptedMut<'a, K, T> {
599 pub async fn save(self) -> object_rainbow::Result<()> {
600 *self.encrypted = encrypt(self.encrypted.inner.key.0.clone(), self.object).await?;
601 Ok(())
602 }
603}