Skip to main content

Crate stegtext

Crate stegtext 

Source
Expand description

Text steganography tool.

Hide secret value in UTF-8 text using homoglyphs.

See also: IDN homograph attack.

§Examples

Hide secret in text:

// secret
const SECRET: [u8; 5] = *b"hello";

// input text
const TEXT: &str = "\
Тhe Нitсhhikеr's Guіdе to thе Galaxy is a 1979 ѕcіеncе fiсtion соmedy
novеl bу Englіѕh author Douglаѕ Adаmѕ, adарtеd frоm the fіrѕt four parts
of hiѕ radiо соmedу ѕеriеѕ оf thе sаmе name.";

// expected output
const EXP: &str = "\
Тhe Нitсhhiker's Guіde tо the Galaxy is a 1979 ѕcіеncе fiсtion соmedy
noνеl by Еnglіsh author Dоuglаs Аdаms, аdарtеd from thе fіrst four parts
of hiѕ radiо соmedу ѕеriеѕ оf thе sаmе name.";

// encode secret, check result
assert_eq!(stegtext::encode(&SECRET, TEXT)?, EXP);

Get secret from text:

// text with embedded secret
const TEXT: &str = "\
Тhe Нitсhhiker's Guіde tо the Galaxy is a 1979 ѕcіеncе fiсtion соmedy
noνеl by Еnglіsh author Dоuglаs Аdаms, аdарtеd from thе fіrst four parts
of hiѕ radiо соmedу ѕеriеѕ оf thе sаmе name.";

// decode secret, check result
assert_eq!(stegtext::decode(TEXT)?, "hello");

Get text embedding capacity:

// input text
const TEXT: &str = "\
Тhe Нitсhhikеr's Guіdе to thе Galaxy is a 1979 ѕcіеncе fiсtion соmedy
novеl bу Englіѕh author Douglаѕ Adаmѕ, adарtеd frоm the fіrѕt four parts
of hiѕ radiо соmedу ѕеriеѕ оf thе sаmе name. Іt centrеѕ оn the
misаdvеntureѕ оf Arthur Dent, the оnly man tо ѕurvive the destruction of
Earth, as he roams the cosmos and learns the truth behind his very
existence. The novel's namesake is an in-universe electronic travel
guide written in the form of an encyclopaedia, through which the story
is framed.";

// calculate capacity, check result
assert_eq!(stegtext::capacity(TEXT), 24);

§Technical Details

The encoded payload begins with a prefix byte, then 0-7 bytes containing the size of the data size, encoded as an unsigned, little-endian integer, and followed by the actual data bytes:

-- payload layout --------------------------------
| PREFIX BYTE | SIZE (0-7 bytes) | DATA BYTES... |
--------------------------------------------------

The prefix byte contains a 4-bit tag, a 3-bit length indicating the number of bytes of SIZE, and one unused bit:

-- prefix byte layout ----------------
| bit: 7   6   5   4   3   2   1   0 |
| use: X   \- LEN -/   \--- TAG ---/ |
--------------------------------------

Encoding process:

  1. The first prefix byte is constructed and appended to the payload buffer. Bits 0..4 are the constant tag (0x5), bits 4..7 encode the number of bytes needed to encode the length of the data, and bit 7 is unused.
  2. The data length is appended to the payload buffer as a variable-length, little-endian integer.
  3. The data bytes are appended to the payload buffer to create a complete payload.
  4. The total number of payload bits are calculated.
  5. The input text is scanned for characters that can be replaced by homoglyphs.
  6. Non-matching characters are passed through to the output unaltered.
  7. When a matching character is encountered it is modified based on the value of the current payload bit:
    • if the current payload bit is set, then the character is replaced with a non-Latin homoglyph character. For example, 'A' (U+0041) is replaced with 'А' (U+0410), 'B' (U+0042) is replaced by 'В' (U+0412), and so on.
    • if the current payload bit is not set, then the character is replaced with a Latin character.
  8. The current payload bit position is incremented.
  9. Steps 5-8 are repeated until the current payload bit position equals the total number of payload bits.
  10. If payload bits remain when the end of the input text is reached, then Err::Capacity is returned.
  11. Once all the payload bits have been encoded, the remaining characters from the input text are passed through to the output unaltered.

Enums§

Err
Encode/decode error.

Functions§

capacity
Get embedding capacity, in bytes.
decode
Extract secret from text and return result as string.
decode_vec
Extract secret from text and return result as byte vector.
encode
Hide secret in text and return result as string.
encode_vec
Hide secret in text and return result as byte vector.