Skip to main content

Encryptor

Struct Encryptor 

Source
#[non_exhaustive]
pub struct Encryptor { /* private fields */ }
Expand description

Builder-style entry point for encryption.

Pick the recipient kind via the constructor — passphrase (Encryptor::with_passphrase) or one or more public keys (Encryptor::with_public_key, Encryptor::with_public_keys). Then optionally set an explicit output path (Encryptor::save_as) or override archive resource caps (Encryptor::archive_limits). Finalize with Encryptor::write, which streams plaintext through the FCA archive layer + XChaCha20-Poly1305 STREAM-BE32 directly to disk.

§Examples

Passphrase:

use ferrocrypt::{Encryptor, secrecy::SecretString};
let pass = SecretString::from("correct horse battery staple".to_string());
let outcome = Encryptor::with_passphrase(pass)
    .write("./payload", "./out", |ev| eprintln!("{ev}"))?;
println!("Encrypted to {}", outcome.output_path.display());

Single public-key recipient:

use ferrocrypt::{Encryptor, PublicKey};
let pk = PublicKey::from_key_file("./keys/public.key");
let outcome = Encryptor::with_public_key(pk)
    .write("./payload", "./out", |ev| eprintln!("{ev}"))?;

Multiple public-key recipients:

use ferrocrypt::{Encryptor, PublicKey};
let alice = PublicKey::from_key_file("./alice/public.key");
let bob = PublicKey::from_key_file("./bob/public.key");
let outcome = Encryptor::with_public_keys([alice, bob])?
    .write("./payload", "./out", |ev| eprintln!("{ev}"))?;

Implementations§

Source§

impl Encryptor

Source

pub fn with_passphrase(passphrase: SecretString) -> Self

Configures passphrase encryption.

The resulting .fcr contains exactly one native argon2id recipient. The passphrase is checked for non-emptiness when Encryptor::write runs; constructing this builder is infallible.

Source

pub fn with_public_key(public_key: PublicKey) -> Self

Configures encryption to one public-key recipient.

This is a convenience wrapper around Encryptor::with_public_keys for the common single-recipient case. As with that constructor, public-key encryption does not authenticate the sender.

Source

pub fn with_public_keys( public_keys: impl IntoIterator<Item = PublicKey>, ) -> Result<Self, CryptoError>

Configures encryption to one or more public-key recipients.

Each recipient entry wraps the same per-file file_key independently, so any listed recipient can decrypt the resulting .fcr with their matching private key.

§Security

Public-key encryption controls who can decrypt the file, not who created it. Anyone with a recipient’s public key can produce a file for that recipient. Use a separate signing layer if recipients must verify sender identity.

§Default-decrypt round-trip

By default the writer caps public_keys.len() at the same HeaderReadLimits::RECIPIENT_COUNT_DEFAULT (64) the reader applies via HeaderReadLimits::default, so a default-configured Decryptor::open can read every file the default Encryptor produces. Lists above the default reject with CryptoError::RecipientCountCapExceeded at Encryptor::write time. To produce a file with more recipients, the caller must opt in via Encryptor::header_read_limits with a raised recipient-count limit; the receiving decryptor must be opened via Decryptor::open_with_limits with matching limits.

§Errors

Returns CryptoError::EmptyRecipientList if the iterator is empty. All public keys in the current v1 implementation are X25519 recipients; future key kinds may add additional mixing-policy checks.

Source

pub fn save_as(self, path: impl AsRef<Path>) -> Self

Sets the encrypted output file path.

When set, this path is used instead of the default {output_dir}/{stem}.fcr destination chosen by Encryptor::write.

Source

pub fn archive_limits(self, limits: ArchiveLimits) -> Self

Overrides the default archive resource caps applied during the writer-side preflight. Useful for callers operating on trusted trees that legitimately exceed the defaults.

§Default-decrypt round-trip

Raising archive_limits above ArchiveLimits::default can produce a .fcr whose archive payload exceeds what a default-configured PassphraseDecryptor / PrivateKeyDecryptor will extract. The receiving decryptor must be configured via PassphraseDecryptor::archive_limits / PrivateKeyDecryptor::archive_limits with limits that match (or exceed) the file’s actual content. Lowering archive_limits only tightens what the encrypt-side preflight accepts and never breaks default round-trip.

Source

pub fn kdf_params(self, params: KdfParams) -> Self

Overrides the Argon2id parameters used by the passphrase recipient (Encryptor::with_passphrase). Has no effect on public-key (Encryptor::with_public_key / with_public_keys) flows, which use X25519 ECDH and never run Argon2id during encryption.

If unset, the writer uses KdfParams::default (1 GiB memory, time_cost 4, parallelism 4). A params.mem_cost below the 19 MiB production memory floor rejects at Encryptor::write time with CryptoError::KdfBelowWriteFloor, so a caller cannot seal a .fcr with weak Argon2id memory; the floor is hard and has no override.

§Default-decrypt round-trip

kdf_params is also checked at Encryptor::write time against the writer’s KdfLimit policy. By default, memory is capped at 1 GiB while time cost and lanes are capped at the v1 format maximum, so KdfParams::default is accepted. A value above the effective policy rejects with the matching typed cap error. To write a .fcr with memory above 1 GiB, or to use a deliberately tightened time-cost or lane policy, configure Encryptor::kdf_limit and set a compatible PassphraseDecryptor::kdf_limit on the receiving decryptor before calling PassphraseDecryptor::decrypt.

Source

pub fn header_read_limits(self, limits: HeaderReadLimits) -> Self

Sets the writer-side header limits.

By default the writer caps the header shape at the same HeaderReadLimits values the default reader uses, so a default Decryptor::open can read every file the default Encryptor produces. This builder raises or tightens those writer-side caps; the receiving decryptor must be opened via Decryptor::open_with_limits with limits that are at least as permissive.

All three axes are checked before encryption work begins: recipient_count, canonical native recipient body_len, and the exact v1 header_len that the writer will emit (ext_len = 0 for current writers). Tightening any axis below the emitted header shape rejects at Encryptor::write time with the same typed cap error the reader would later return.

Source

pub fn kdf_limit(self, limit: KdfLimit) -> Self

Sets the writer-side KDF resource policy for passphrase encryption.

The policy caps Argon2id memory cost, time cost, and lane count before any encryption work begins. The default policy accepts KdfParams::default and rejects memory above 1 GiB unless the caller opts into a higher memory cap. Time cost and lanes default to the v1 format maximum, so they only reject when the caller tightens them.

Use this builder together with Encryptor::kdf_params to raise the memory ceiling or to tighten time cost or lanes. The receiving passphrase decryptor must be configured via PassphraseDecryptor::kdf_limit with a policy that accepts the same parameters.

Has no effect on public-key (Encryptor::with_public_key / with_public_keys) flows, which never run Argon2id during encryption.

Source

pub fn write( self, input: impl AsRef<Path>, output_dir: impl AsRef<Path>, on_event: impl Fn(&ProgressEvent), ) -> Result<EncryptOutcome, CryptoError>

Encrypts input and writes the resulting .fcr file.

input may be a regular file or a directory. Directory inputs are encoded as a FerroCrypt Archive (FCA) payload before payload encryption. The default destination is {output_dir}/{stem}.fcr; use Encryptor::save_as to supply an explicit output file path.

§Errors

Returns CryptoError::InvalidInput for invalid input paths, output conflicts, unsupported archive entries, empty passphrases, archive cap violations, or invalid KDF settings. Returns CryptoError::Io for filesystem failures. Returns authentication or internal crypto errors if key wrapping or payload streaming fails.

Trait Implementations§

Source§

impl Debug for Encryptor

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> Same for T

Source§

type Output = T

Should always be Self
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.