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