|\ /|     scroll down for older posts.
= o.o =

Samstag, 3. Juni 2017

gdzip released

I humbly announce the release of gdzip.
Gdzip is a command line tool to compress and encrypt files or folders. It is written in Go.

Executable binaries as well as the source code can be downloaded at Github:
Source code: https://github.com/w33zl3p00tch/gdzip
Releases: https://github.com/w33zl3p00tch/gdzip/releases

Internally, the given files and/or folders are compressed and stored as tar.gz archives that retain the original file metadata.
The data are split into chunks while encrypting, and encryption is done done using AES256-GCM and/or ChaCha20-Poly1305. All this happens in RAM, so no temporary files will be used.

Keys are generated using the scrypt key derivation function.

The encrypted files provide no information about their contents or their contents' filenames.

Encrypted files may be safely renamed and even the extension may be altered or left out.

Please report any bugs you might find. Suggestions and feature requests are welcome.

Donnerstag, 1. Juni 2017

Sieve of Eratosthenes in Python

I've recently discovered the magic of hash tables. Here is a version of the Sieve of Eratosthenes that is pretty fast, given it's written in Python:

Sonntag, 6. November 2016

Portrait Viktoria

Portrait Viktoria Monhor, digital painting, 2016

Montag, 31. Oktober 2016

Some thoughts that might be useful for painters

The best book about painting technique I have read is Kurt Wehlte's "Werkstoffe und Techniken der Malerei".


All you'll ever need to paint a realistic painting is a small set of colors. Frans Hals used these:

Black, Red, Ochre, White. That's it.

For ambitious paintings that require lots of different colors I recommend the following travel-friendly palette:

Light Ochre (be sure not to buy a color that has been mixed with white.)
Raw Umber (may be greenish)
Cadmium Red (very strong, be careful with it; take a middle or dark hue)
Ultramarine Blue (dark, can always be mixed with white for light blue)
Titanum White (it is opaque)
Bone Black

Optional colors:

Burnt Sienna (may be achieved by mixing Umber, Ochre and a bit Red)
Burnt Umber (warmer color)
Scarlet Lake (the Naphtol Azo Version; natural scarlet lake is rarely sold; useful for reddish skin tones and lips)
Cadmium Yellow (most of the time, ochre mixed with white is yellow enough)
Chrome-oxide-hydrate Green (most other green hues can be mixed from blue and ochre/yellow)
Zinc White (translucent; aids as UV filter by turning UV light into visible light; useful for brightening lightly)

- Umber contains manganese; it aids as siccative in oil painting, which means it makes the colors that are mixed with it dry faster. If you are using lots of umber, your painting may be dry to the touch within one or two days, as opposed to Zinc White, which takes weeks to dry.


If you want to work fast or are travelling, acrylic colors work best. Good acrylic colors are even useful as watercolors. Good colors are composed of only one single pigment and acrylic resin without filler. Excellent brands (in descending order of quality): Golden Acrylics, Liquitex, Schmincke.
Oil colors are mostly of good quality, regardless from which company they come from. But if you want to work with the best possible colors, you'll sooner or later buy "Michael Harding's artists colours" or make your own.

Samstag, 29. Oktober 2016


Sonntag, 23. Oktober 2016

Marie Lienhard, Plaisirs et terreurs de la lévitation, left part, pencil on paper, 42 x 60 cm

Sadly, I cannot afford it at the moment. I would have bought it on the spot. Marie's homepage:

Sonntag, 16. Oktober 2016

Dichtung nach Celan

Dem lieben Gottfried Benn wurde einst die Frage gestellt, ob Dichtung das Leben bessern könne. Ich erlaube mir, die Frage zu stellen, ob das Leben das Leben bessern könne.

Wer schweren Gemüts ist, überspringe das folgende.

Einst wurde ein Polizeibeamte zum Ort eines Autounfalls gerufen.
Glimpflich verlief das Desaster für fast eine ganze Familie.
Die letzten Worte, ausgesprochen von der kleinen Tochter, gefangen im Drahtzaun, waren:
"Kitten in a blender..."

Sonntag, 2. Oktober 2016

Farewell, Linux! Welcome, FreeBSD!

Most Linux distributions have never been elegant operating systems. Under the hood they carry a metric crapton of kludge. (Please pardon my Spanish.)

systemd is a disaster. Nothing can fix that. Here is the newest SNAFU:

There are more secure (http://www.openbsd.org) and elegant (https://www.freebsd.org) options to consider. Let's hope they won't get too popular with the greedy corporations that rode Linux into the mess it sits in.

FreeBSD, by the way, is excellently documented, and I learned more about UNIX by testing it than 11 years of professional experience with Linux could ever teach me.

And demonettes are by far sexier than a fat penguin. *tips fedora*

Sonntag, 25. September 2016

untitled, acrylic on cotton, 40 x 50 cm

Freitag, 26. August 2016

Nearest Mean Interpolation: a method to scale up images

Here is a nice and clean method of scaling up an image to double its size:

screenshot of a comment in pepperpickle's source code

I found it in the research paper that describes the HCRHide image steganography algorithm: https://www.researchgate.net/publication/272307744_A_high-capacity_reversible_data_hiding_method_HCRHide

The main quality of this algorithm is that the original image can be reconstructed without any loss of color information. Pixels a, b, c and d are taken from the original image. the three lambda-pixels we get for each original pixel can be used to store information steganographically. Here is my golang implementation of the NMI scaling-algorithm:

// scaleNMI scales up an image using the NMI method (Nearest Mean
// Interpolation)
Here is how NMI works:
four neighbouring pixels of the original image are obtained:
|    |    |
| a  | b  |
|    |    |
| c  | d  |

between those pixels, new ones are inserted:
|    |    |    |
| a  | λ₁ | b  |
|    |    |    |
| λ₂ | λ₃ | λ₄ |
|    |    |    |
| c  | λ₅ | d  |

The color values for the new pixels are calculated using the following


Those are calculated in the next pixel set as λ₁ and λ₂:

The original formula for λ₃ is:

Per pass, the image is scaled up to double its size.
func scaleNMI(src image.Image) image.Image {
        bounds := src.Bounds()
        w, h := bounds.Max.X, bounds.Max.Y
        dest := image.NewRGBA(image.Rect(0, 0, w*2, h*2))
        dX, dY := 0, 0

        for x := 0; x < w; x++ {
        for y := 0; y < h; y++ {
        a := src.At(x, y)
        b := src.At(x+1, y)
        c := src.At(x, y+1)
        d := src.At(x+1, y+1)

        if x > w-2 {
        b = a
        d = a
        if y > h-2 {
        c = a
        d = a

        aR, aG, aB, aA := a.RGBA()
        bR, bG, bB, bA := b.RGBA()
        cR, cG, cB, cA := c.RGBA()
        dR, dG, dB, dA := d.RGBA()

        l1R, l1G, l1B, l1A :=
        ((aR + bR) / 2), // >> 1: divide by 2
        ((aG + bG) / 2),
        ((aB + bB) / 2),
        ((aA + bA) / 2)
        l2R, l2G, l2B, l2A :=
        ((aR + cR) / 2),
        ((aG + cG) / 2),
        ((aB + cB) / 2),
        ((aA + cA) / 2)
        l3R, l3G, l3B, l3A :=
        ((aR + bR + cR + dR) / 4), // >> 2: divide by 4
        ((aG + bG + cG + dG) / 4),
        ((aB + bB + cB + dB) / 4),
        ((aA + bA + cA + dA) / 4)

        dest.Set(dX, dY, color.RGBA{
        uint8(aR / 256), // >> 8 divide by 256
        uint8(aG / 256),
        uint8(aB / 256),
        uint8(aA / 256)})
        dest.Set(dX+1, dY, color.RGBA{
        uint8(l1R / 256),
        uint8(l1G / 256),
        uint8(l1B / 256),
        uint8(l1A / 256)})
        dest.Set(dX, dY+1, color.RGBA{
        uint8(l2R / 256),
        uint8(l2G / 256),
        uint8(l2B / 256),
        uint8(l2A / 256)})
        dest.Set(dX+1, dY+1, color.RGBA{
        uint8(l3R / 256),
        uint8(l3G / 256),
        uint8(l3B / 256),
        uint8(l3A / 256)})

        dY += 2
        dY = 0
        dX += 2

        return dest

Montag, 22. August 2016

Steganography: A Visual Comparison Of Least Significant Bit Embedding Methods In Images

Bonbon for reading this: here is an image of a Beluga whale. It contains the whole novel "Moby Dick" by Herman Melville, which is in the public domain and was taken from Project Gutenberg:

This image can be decrypted with the current stable version of pepperpickle, v0.0.3.
The decryption password is: mobydick

Credits: taken from Wikipedia; original photo by Steve Snodgrass, licensed under CC-by-SA

I've been adding more flexibility to my development version of pepperpickle, and made some tests. Here are a few results.
I recommend scrolling down first, to get an overview of the changes in image quality.

The original images I used are as follows:

Baboon, Lena and sweet peppers, each 256x256 pixels in size.

I have embedded random data in the whole available storage space. When using only the Least Significant Bit (LSB) for embedding, an additional storage space of 24576 bytes for each image can be achieved, which is quite a lot:

As can be seen, there is no visual difference between the stego images and the originals. Using the second LSB and the first LSB, an additional storage capacity of 49152 bytes per image can be achieved. Yet, I had to slightly turn down the most intensive color values to compensate for an integer overflow I am currently weeding out:

Apart from being slightly brighter, there is also no visual difference between the images. This will change drastically later on, but first, let's try the method of threshold-based embedding I wrote about earlier.
This gives us varying storage capacity, 41278 bytes for Baboon, 43434 bytes for Lena and a whopping 63528 bytes for the peppers:

Still an excellent image quality...
With 3 LSBs we get 73728 bytes per image:

Nothing critical, yet.
Let's try 4 LSBs. 98304 bytes per image are used for data storage:

Apart from some artefacts due to the aforementioned overflow bug, the image quality is still quite acceptable.
Let's go for 5 LSBs (122880  bytes):

We're losing quite some quality now, but the noisy Baboon image is a good carrier.
6 LSBs (147456 bytes):

The image quality is now unacceptably low. The noise dominates the image information.
For completeness' sake here are 7 LSBs (172032 bytes):

Using an additional bit would completely destroy the image and result in random noise:

random noise or encrypted data? Who can tell...

When we zoom into the noise, we get something that resembles some newer artwork by Bridget Riley, whose art I honestly admire (hint for art historians and steganalysts alike: maybe she embedded something in her paintings...):

Sonntag, 21. August 2016


After a lot of theoretical work I am in the middle of completely rewriting pepperpickle. Currently I am half through the encryption/embedding process...