pub struct EmbedPipeline<KDF, AEAD, COST> { /* private fields */ }Expand description
The orchestrator of layers 1 to 4.
Generic over the three components that have a choice of implementation, so
that a test can substitute a cheap key deriver or a stub cost model without
any of the code below knowing. The production instantiation is built by
EmbedPipeline::default_secure.
Implementations§
Source§impl<KDF, AEAD, COST> EmbedPipeline<KDF, AEAD, COST>
impl<KDF, AEAD, COST> EmbedPipeline<KDF, AEAD, COST>
Sourcepub fn new(kdf: KDF, aead: AEAD, cost: COST) -> Self
pub fn new(kdf: KDF, aead: AEAD, cost: COST) -> Self
Assembles a pipeline from its three components.
Unconstrained on purpose: the bounds belong on the operations, not on construction, so that a caller can hold a pipeline built from anything and only meet the requirements when it embeds or extracts.
Source§impl EmbedPipeline<Argon2Kdf, XChaCha20Poly1305Cipher, HillCostProvider>
impl EmbedPipeline<Argon2Kdf, XChaCha20Poly1305Cipher, HillCostProvider>
Sourcepub fn default_secure() -> Self
pub fn default_secure() -> Self
Builds the pipeline this project considers secure: Argon2id at 128 MiB and four passes, XChaCha20-Poly1305, and the HILL cost model.
There is no constructor that weakens any of the three. A pipeline whose components were chosen at run time would look identical at the API surface to this one and behave nothing like it.
Source§impl<KDF, AEAD, COST> EmbedPipeline<KDF, AEAD, COST>
impl<KDF, AEAD, COST> EmbedPipeline<KDF, AEAD, COST>
Sourcepub fn embed(
&self,
image_path: &Path,
plaintext: Zeroizing<Vec<u8>>,
password: Zeroizing<Vec<u8>>,
output_path: &Path,
) -> Result<EmbedReport, PipelineError>
pub fn embed( &self, image_path: &Path, plaintext: Zeroizing<Vec<u8>>, password: Zeroizing<Vec<u8>>, output_path: &Path, ) -> Result<EmbedReport, PipelineError>
Hides plaintext in the container at image_path and writes the result
to output_path.
Both secrets are taken by value in a Zeroizing wrapper: the pipeline
becomes their owner and wipes them at the point in the chain where they
stop being needed, which a borrow could not guarantee.
§Errors
Returns a PipelineError wrapping the error of whichever layer refused
the operation: an unusable container, an unstable perceptual hash, a
smooth image, a payload that does not fit, a failure of the coder, or a
file that could not be written.
Sourcepub fn extract(
&self,
stego_path: &Path,
password: Zeroizing<Vec<u8>>,
) -> Result<(Zeroizing<Vec<u8>>, ExtractReport), PipelineError>
pub fn extract( &self, stego_path: &Path, password: Zeroizing<Vec<u8>>, ) -> Result<(Zeroizing<Vec<u8>>, ExtractReport), PipelineError>
Recovers the message hidden in the stego image at stego_path.
§Why extraction needs no cost map
STC decoding operates on the syndrome H x stego (mod 2) taken over
all the positions of a region. The receiver does not need to know which
pixels were modified, and there is no position list to transmit or store:
it only has to reproduce the permutation, which follows from the same
stc_seed derived from the same MasterKey derived from the same
password and the same image. That is the whole reason the container
carries no metadata at all — and the reason the expensive half of
embedding, the HILL analysis, has no counterpart here.
§Why it reads two kinds of container
A container may have been produced by crate::generate rather than by
EmbedPipeline::embed, and nothing in the file says which — a marker
would be the one piece of metadata this design does not carry. Both
readings are therefore attempted under one key derivation, and every
failure is the single failure below. The second reading costs a stream
cipher over the container and no second Argon2id pass, because both
constructions derive from the same perceptual hash of the same image.
§Errors
Returns a PipelineError wrapping the error of whichever layer
refused: an unusable file, a hash too unstable to reproduce, a coder
failure, or AEADError::AuthenticationFailed — which collapses a wrong
password, a wrong image and a damaged payload into one answer on purpose.
Auto Trait Implementations§
impl<KDF, AEAD, COST> Freeze for EmbedPipeline<KDF, AEAD, COST>
impl<KDF, AEAD, COST> RefUnwindSafe for EmbedPipeline<KDF, AEAD, COST>
impl<KDF, AEAD, COST> Send for EmbedPipeline<KDF, AEAD, COST>
impl<KDF, AEAD, COST> Sync for EmbedPipeline<KDF, AEAD, COST>
impl<KDF, AEAD, COST> Unpin for EmbedPipeline<KDF, AEAD, COST>
impl<KDF, AEAD, COST> UnsafeUnpin for EmbedPipeline<KDF, AEAD, COST>
impl<KDF, AEAD, COST> UnwindSafe for EmbedPipeline<KDF, AEAD, COST>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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