Skip to content

RnnStega

stegobox.codec.RnnStega

Bases: BaseCodec

RnnStega is a steganography method for text.

RnnStega doesn't use any payload. It converts encrypted secret text into smooth statements that are difficult to detect abnormality.

Source code derived from: mickeysjm/StegaText

Source code in stegobox/codec/rnn_stega/rnn_stega.py
class RnnStega(BaseCodec):
    """
    RnnStega is a steganography method for text.

    RnnStega doesn't use any payload. It converts encrypted secret text into smooth
    statements that are difficult to detect abnormality.

    Source code derived from:
    [mickeysjm/StegaText](https://github.com/mickeysjm/StegaText)
    """

    def __init__(self):
        self.temp = 1.0
        self.precision = 26
        self.topk = 50
        self.nucleus = 0.95
        self.enc, self.model, self.device = get_model()
        self.device = str(self.device)
        self.delta = 0.01
        if self.delta:
            self.nucleus = 2 ** (-1.0 * self.delta)

    def encode(self, carrier: str, payload=None) -> str:
        """encrypt secret plaintext to message bits & encode message bits to covertext

        Args:
            carrier: secret plaintext to send
            payload: should be kept as None

        Returns:
            covertext: covertext looks like normal text
        """

        plaintext = carrier
        message_ctx = [self.enc.encoder["<|endoftext|>"]]
        plaintext += "<eos>"
        message = decode_arithmetic(
            self.model,
            self.enc,
            plaintext,
            message_ctx,
            device=self.device,  # type: ignore
            precision=40,
            topk=60000,
        )

        context = ""
        context_tokens = encode_context(context, self.enc)

        out, nll, kl, words_per_bit = encode_huffman(
            self.model,
            self.enc,
            message,
            context_tokens,
            bits_per_word=4,
            device=self.device,  # type: ignore
        )

        covertext = self.enc.decode(out)
        return covertext

    def decode(self, carrier: str) -> str:
        """decode covertext to message bits & map message bits back to original text

        Args:
            carrier: received covertext

        Returns:
            reconst: recovered plaintext
        """
        covertext = carrier
        context = ""
        context_tokens = encode_context(context, self.enc)

        message_rec = decode_huffman(
            self.model,
            self.enc,
            covertext,
            context_tokens,
            bits_per_word=4,
            device=self.device,  # type: ignore
        )

        message_ctx = [self.enc.encoder["<|endoftext|>"]]
        reconst = encode_arithmetic(
            self.model,
            self.enc,
            message_rec,
            message_ctx,
            device=self.device,  # type: ignore
            precision=40,
            topk=60000,
        )
        reconst = self.enc.decode(reconst[0])
        return reconst

encode(carrier, payload=None)

encrypt secret plaintext to message bits & encode message bits to covertext

Parameters:

Name Type Description Default
carrier str

secret plaintext to send

required
payload

should be kept as None

None

Returns:

Name Type Description
covertext str

covertext looks like normal text

Source code in stegobox/codec/rnn_stega/rnn_stega.py
def encode(self, carrier: str, payload=None) -> str:
    """encrypt secret plaintext to message bits & encode message bits to covertext

    Args:
        carrier: secret plaintext to send
        payload: should be kept as None

    Returns:
        covertext: covertext looks like normal text
    """

    plaintext = carrier
    message_ctx = [self.enc.encoder["<|endoftext|>"]]
    plaintext += "<eos>"
    message = decode_arithmetic(
        self.model,
        self.enc,
        plaintext,
        message_ctx,
        device=self.device,  # type: ignore
        precision=40,
        topk=60000,
    )

    context = ""
    context_tokens = encode_context(context, self.enc)

    out, nll, kl, words_per_bit = encode_huffman(
        self.model,
        self.enc,
        message,
        context_tokens,
        bits_per_word=4,
        device=self.device,  # type: ignore
    )

    covertext = self.enc.decode(out)
    return covertext

decode(carrier)

decode covertext to message bits & map message bits back to original text

Parameters:

Name Type Description Default
carrier str

received covertext

required

Returns:

Name Type Description
reconst str

recovered plaintext

Source code in stegobox/codec/rnn_stega/rnn_stega.py
def decode(self, carrier: str) -> str:
    """decode covertext to message bits & map message bits back to original text

    Args:
        carrier: received covertext

    Returns:
        reconst: recovered plaintext
    """
    covertext = carrier
    context = ""
    context_tokens = encode_context(context, self.enc)

    message_rec = decode_huffman(
        self.model,
        self.enc,
        covertext,
        context_tokens,
        bits_per_word=4,
        device=self.device,  # type: ignore
    )

    message_ctx = [self.enc.encoder["<|endoftext|>"]]
    reconst = encode_arithmetic(
        self.model,
        self.enc,
        message_rec,
        message_ctx,
        device=self.device,  # type: ignore
        precision=40,
        topk=60000,
    )
    reconst = self.enc.decode(reconst[0])
    return reconst