EncryptionService

Struct EncryptionService 

Source
pub struct EncryptionService { /* private fields */ }
Expand description

Manages encryption keys and provides XChaCha20-Poly1305 encryption/decryption

This implements the security model described in the README:

  • Files are encrypted using XChaCha20-Poly1305 for authenticated encryption
  • Chunked format enables random-access decryption for efficient range reads

Implementations§

Source§

impl EncryptionService

Source

pub fn new(key_hex: &str) -> Result<Self, EncryptionError>

Create a new encryption service from a hex-encoded key string

Source

pub fn from_key(key: [u8; 32]) -> Self

Create a new encryption service from a raw 32-byte key.

Source

pub fn fingerprint(&self) -> String

SHA-256 fingerprint of the key, first 8 bytes hex-encoded (16 hex chars). Short enough to display in UI, long enough to detect wrong keys.

Source

pub fn new_with_key(key_bytes: &[u8]) -> Self

Create an encryption service with a raw key (for testing)

Source

pub fn key_bytes(&self) -> [u8; 32]

Return the raw 32-byte key.

Source

pub fn encrypt(&self, plaintext: &[u8]) -> Vec<u8>

Encrypt data using chunked XChaCha20-Poly1305 format. Returns: [base_nonce: 24 bytes][ciphertext with auth tags] For small data (single chunk), this is equivalent to standard AEAD. For large data, each chunk is independently encrypted for random-access.

Source

pub fn decrypt(&self, encrypted_data: &[u8]) -> Result<Vec<u8>, EncryptionError>

Decrypt data in chunked format: [nonce (24 bytes)][ciphertext chunks…]

Source

pub fn encrypt_chunked(&self, plaintext: &[u8]) -> Vec<u8>

Encrypt data using chunked XChaCha20-Poly1305 format. Returns: [base_nonce: 24 bytes][chunk_0][chunk_1]... Each chunk is independently encrypted, enabling random-access decryption.

Source

pub fn decrypt_chunk( &self, ciphertext: &[u8], chunk_index: usize, ) -> Result<Vec<u8>, EncryptionError>

Decrypt a specific chunk from chunked encrypted data. Enables random-access decryption without reading preceding chunks.

Source

pub fn decrypt_chunked( &self, ciphertext: &[u8], ) -> Result<Vec<u8>, EncryptionError>

Decrypt all chunks from chunked encrypted data.

Source

pub fn decrypt_range( &self, ciphertext: &[u8], plaintext_start: u64, plaintext_end: u64, ) -> Result<Vec<u8>, EncryptionError>

Decrypt a specific plaintext byte range from encrypted data.

The ciphertext must start with the nonce (first 24 bytes) but may be truncated after the chunks needed for the requested range.

Returns exactly the plaintext bytes from plaintext_start to plaintext_end.

Source

pub fn decrypt_range_with_offset( &self, nonce: &[u8], encrypted_chunks: &[u8], first_chunk_index: u64, plaintext_start: u64, plaintext_end: u64, ) -> Result<Vec<u8>, EncryptionError>

Decrypt a plaintext byte range using nonce from DB and partial chunk data.

This is the efficient method for encrypted range requests:

  • nonce: 24-byte nonce stored in DB at import time
  • encrypted_chunks: Raw encrypted chunk bytes (NO nonce prefix)
  • first_chunk_index: Which chunk index the encrypted_chunks starts at
  • plaintext_start, plaintext_end: Absolute byte positions in original file

Example: To read plaintext bytes 500,000-600,000:

  1. Calculate needed chunks: encrypted_chunk_range(500000, 600000) -> chunks 7-9
  2. Fetch encrypted bytes from cloud at those positions
  3. Call decrypt_range_with_offset(nonce, chunks, 7, 500000, 600000)
Source

pub fn derive_scoped(&self, release_id: &str) -> EncryptionService

Derive a per-release encryption service.

Uses HKDF: master_key + “bae-release-v1:{release_id}” -> 32-byte key. Deterministic: same master + release_id always gives the same key.

Source

pub fn derive_key(&self, info: &str) -> [u8; 32]

Derive a 32-byte key using HKDF-SHA256 with the given info label.

The derivation is deterministic: same master key + same info string always produces the same derived key.

  • Salt: HMAC-SHA256(master_key, "bae-hkdf-salt-v1")
  • IKM: master key
  • Info: caller-provided label

Trait Implementations§

Source§

impl Clone for EncryptionService

Source§

fn clone(&self) -> EncryptionService

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for EncryptionService

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromRef<T> for T
where T: Clone,

§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more