gotpi

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 15, 2026 License: GPL-2.0 Imports: 5 Imported by: 0

README

GOTPi

GOTPi (Golang + OTP + images) is a lightweight Go CLI and library for experimenting with One-Time Pad (OTP) encryption using images as keys. It allows to generate random noise keys as PNGs (either Grayscale or RGB) and use them to bitwise-encrypt and decrypt image files.

It supports key generation in two modes: standard black and white (Grayscale) or full color (RGB).

bw rgb
bw-key rgb-key
gotpi key-gen gotpi key-gen --rgb

Two-Time Pad security

This is inspired by this question on the secutiy of Two-Time Pad on StackOverflow. Indeed this tool is a great way to visualize why key reuse is fatal for OTP security.

If two different messages ($m_1​$ and $m_2​$) are encrypted with the same key ($k$), an attacker can XOR the two ciphertexts together. This removes the key and leaves the combined original messages in the hand of the adversary ($m_1 \oplus m_2​$).

$$ c_1\oplus c_2 = (m_1 \oplus k) \oplus (m_2 \oplus k) = m_1 \oplus m_2 $$

Reusing the key multiple times gives the encryption depth, the more depth given, the more likely it is that information leaks. The attack is called crib dragging.

If two images are encrypted using the same key, hence violating the rule of one-time, then an adversary can compute the xor of the two encryptions and gain an advantage, graphically:

send-cash.enc.png vibrant.enc.png xoring leaks information
examples/send-cash.enc.png $\oplus$ examples/vibrant.enc.png $=$ examples/xor.png

Examples

$m$ $k$ $m \oplus k = c$
examples/vibrant.png $\oplus$ examples/rgb-key $=$ examples/vibrant.enc.rgb.png

gotpi enc -f vibrant.png -k rgb-key.png -o vibrant.enc.rgb.png --rgb

$c$ $k$ $c \oplus k = m$
examples/vibrant.enc.rgb.png $\oplus$ examples/rgb-key $=$ examples/vibrant.dec.rgb.png

gotpi dec -f vibrant.enc.rgb.png -k rgb-key.png -o vibrant.dec.rgb.png --rgb

$k$ $m$ $k \oplus m = c$
examples/bw-key $\oplus$ examples/smiley.png $=$ examples/smiley.enc.png

gotpi enc -f smiley.png -k bw-key.png -o smiley.enc.png

$c$ $k$ $c \oplus k = m$
exmaples/smiley.enc.png $\oplus$ examples/bw-key $=$ examples/smiley.dec.png

gotpi dec -f smiley.enc.png -k bw-key.png -o smiley.dec.png

Installing

As a CLI Utility
go install github.com/micheledinelli/gotpi/cmd/gotpi@latest
gotpi --help

[sub]Command required
usage: One-Time Pad image encryptor <Command> [-h|--help] [-v|--verbose]
                                    [-c|--rgb]

                                    encrypt and decrypt images using OTP images
                                    as keys

Commands:

  key-gen  Generate a new OTP key image
  enc      Encrypt an image using an OTP key image
  dec      Decrypt an image using an OTP key image
  xor      XOR two images together

Arguments:

  -h  --help     Print help information
  -v  --verbose  Print the encrypted image to terminal. Default: false
  -c  --rgb      use RGB mode instead of black and white. Default: false
As a Package
go get -u github.com/micheledinelli/gotpi
package main

import (
	"image"
	"image/png"
	"os"

	"github.com/micheledinelli/gotpi"
)

func main() {
	colored := true

	// Generate a key of 256x256 pixels
	k := gotpi.KeyGen(256, colored)

	// Load an image
	path := "image.png"
	f, err := os.Open(path)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	img, _, err := image.Decode(f)
	if err != nil {
		panic(err)
	}

	// Encrypt the image
	out := gotpi.Encrypt(img, k, colored)

	// Save the output
	outF, err := os.Create("out.png")
	if err != nil {
		panic(err)
	}
	defer outF.Close()
	if err := png.Encode(outF, out); err != nil {
		panic(err)
	}
}

Note

If you use a Grayscale key on an RGB image, the output will lose its color data because the key doesn't have enough "depth" to cover the R, G, and B channels.

$m$ $k$ $c \oplus k = m$
examples/vibrant.png $\oplus$ examples/bw-key $=$ examples/vibrant.enc.png

gotpi enc -f vibrant.png -k bw-key.png -o vibrant.enc.png

$c$ $k$ $c \oplus k = m$
examples/vibrant.enc.png $\oplus$ examples/bw-key $=$ examples/vibrant.dec.png

gotpi dec -f vibrant.enc.png -k bw-key.png -o vibrant.dec.png

The opposite does work

$k$ $m$ $k \oplus m = c$
examples/bw-key $\oplus$ examples/abstract.png $=$ examples/abstract.enc.rgb.png

gotpi enc -f abstract.png -k rgb-key.png -o abstract.enc.rgb.png

$c$ $k$ $c \oplus k = m$
examples/abstract.enc.rgb.png $\oplus$ examples/rgb-key $=$ examples/abstract.dec.rgb.png

gotpi dec -f abstract.enc.rgb.png -k rgb-key.png -o abstract.dec.rgb.png

Documentation

Index

Constants

This section is empty.

Variables

View Source
var MonochromeModel color.Model = color.ModelFunc(monoModel)

The MonochromeModel converts colors to black or white based on their luminance. Colors with luminance below the midpoint are converted to black, while those above are converted to white. More at https://github.com/ev3go/ev3dev/blob/a5fda5c6a492269e01b184046ed42dc4a1dfe8c9/fb/mono.go#L104

Functions

func Decrypt

func Decrypt(img image.Image, keyImg image.Image, rgb bool) image.Image

Decrypt decrypts an input image using a key image. The input image is first resized to match the key image dimensions. If rgb is true, decryption is performed per RGB channel using XOR. If rgb is false, the image is converted to monochrome and decrypted using a black-and-white XOR-style operation. The resulting decrypted image is returned.

func Encrypt

func Encrypt(img image.Image, keyImg image.Image, rgb bool) image.Image

Encrypt encrypts an input image using a key image. The input image is first resized to match the key image dimensions. If rgb is true, encryption is performed per RGB channel using XOR. If rgb is false, the image is converted to monochrome and encrypted using a black-and-white XOR-style operation. The resulting encrypted image is returned.

func KeyGen

func KeyGen(kw int, rgb bool) image.Image

KeyGen generates a new one-time pad (OTP) key image. The key image is always square with dimensions (kw × kw) which stands for key width. If rgb is true, a full-color RGB key is generated. If rgb is false, a black-and-white (monochrome) key is generated.

An RGB key can encrypt both colored and grayscale images. A black-and-white key should only be used with monochrome images; using it to encrypt a colored image will discard color information and prevent successful decryption.

Types

type Pixel

type Pixel bool
const (
	Black Pixel = true
	White Pixel = false
)

func (Pixel) RGBA

func (c Pixel) RGBA() (r, g, b, a uint32)

Directories

Path Synopsis
cmd
gotpi command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL