Comment: This is how I plan on embedding an encrypted Easter Egg video message

Started by Matty, February 18, 2025, 22:07:33

Previous topic - Next topic

Matty

Greetings friends...

Some of my games I include hidden Easter Egg messages that either fire once on a certain date/time or at some other event.

With an engine that uses shaders that you can write yourself, it's pretty easy to hide an encrypted message in a plain old image that just looks like 'garbage' and decrypt it in the shader at runtime.

A very simple technique is this, including some pseudocode:

Original image / video:
Apply a reversible mathematical operator to the image that produces effectively 'garbage' data and save that as your image. For example, XORing the image's pixels with its own UV coordinates is a possibility, all the values remaining normalised between 0 and 1.

In the shader:
Take the texels of the image and apply the reverse of the mathematical function so that when the image is displayed, instead of the garbage image that is sitting in the folder on disk, the user gets a lovely happy message from the developer instead.

So outside of the game you'd prepare your image/video as normal, then apply a reversible mathematical operator to it to turn it into junk that can't be understood on visual inspection, and then in game - in your shader, you apply the reverse of the mathematical operator and voila, you get your original image back without changing the file that sits on disk.

I plan on doing something similar with an Easter Egg greeting of sorts in my game if it's run on a certain date/time.

Pseudo code:

For each pixel in image:
  Apply operator to turn pixel into a different rgb
Save resulting image to disk.

In game:
For each pixel in 'garbage seeming image' apply reverse operator.
Display resulting image on screen.

Derron

You can simply add the easter-egg-image in your source/media folder ... or sourcecode.

People these days are lucky to be able to navigate an file explorer ... or are so tech savvy that they can scan binaries for hidden information (or use tools to do so). People investing time to find things ... why trying to make it hard for them. And people who are not able or do not care... why investing time to hide things from them so hard?



Only easter eggs I placed in my game is christmas time ... with terrorists costumed as santa, christmas trees in the building etc. Despite that some media elements (news, ads, ...) contain references to eg me (I get arrested for stealing a plastic xxx doll, or will get taken to court for not writing enough news for the game, ...).


bye
Ron

col

Hey Matty,

Your idea creates a scrambled image, which some may find as a challenge to crack (unless you want this :) ).
You can go one better and hide a whole completely different image inside a regular looking image without anyone knowing anything about it - this is a technique that comes under the umbrella of Steganography.

The simplest way to explain is:

To hide 1 image inside another:
1. Take any 2 images - same width and height unless you want to pad, which can be done with more work.
2. Each pixel is RGB, with 8 bits for each pixel.
3. Keep the high 4bits of the image that you want people to see.
4. Keep the high 4 bits of the image that you to hide and shift those 4 high bits right into the lower 4 bits.
5. Merge the original high 4bits with the 'now lower 4bits'. This creates an image that is almost like the original that you want people to see - you could only see the difference when comparing the original with the modified image.

To show the hidden image:
6. Take each of the lower 4bits of each pixel RGB and shift them left 4 bits into the higher 4bits and leave the lower 4bits as 0s.

Show hidden image from step 6, which will almost be the same as the original of the image that you want to hide - voila camouflage 2 perfectly good images into 1 ;)

No one would ever know that the 'hidden' image is there. Some super-ace forensic tools may find it by brute force, but meh... whatever.
https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."

Derron

Can't you use a shader then to have 1 texture and draw two different "images" with it? Saves texture space :p
(dunno about the shader costs .... think they are way higher then... but VRAM is costly these days)


bye
Ron

Matty

You could have even more than that really....if you wanted to use 8 bit image formats rather than 32 bit colour you could easily fit 4 images into 1. As long as they were each 8 bit.

col

Cool eh.
Wouldn't you see the images if you view the main image as 32bit though? Or did I misunderstand your thoughts there?
https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."

Matty

No I plan on making the image stored on disk and using simple xor encryption with a random number generator seeded with the pixel position in the image so that it looks like just a garbage coloured white noise image on inspection but actually holds a series of images in it that you can't see until you unscramble it.

col

Ahh got ya. You did mention a garbage image in your first post  8)

For those that are interested you can find the half-life image is actually inside the blitzmax logo image:
Download the blitzmax logo only, and see if you can find it :)

The 'only' way you'll ever see the half-life logo is by extracting it with this code:
Code: BASIC
Function ExtractPixmap:TPixmap(pixmap:TPixmap)
    Local outPixmap:TPixmap = CreatePixmap(PixmapWidth(pixmap), PixmapHeight(pixmap), PF_RGBA)
    
    For Local y:Int = 0 Until PixmapHeight(pixmap)
        For Local x:Int = 0 Until PixmapWidth(pixmap)
            Local rgbaShow:Int = ReadPixel(pixmap, x, y)
            
            Local rgbaOut:Int = (rgbaShow & $0F0F0F0F) Shl 4
            WritePixel(outPixmap, x, y, rgbaOut)
        Next
    Next
    
    Return outPixmap
EndFunction

Local blitzmaxPixmap:TPixmap = LoadPixmap("blitzmax.png")
Local halflifePixmap:TPixmap = ExtractPixmap(blitzmaxPixmap)
    
Local blitzmaxImage:TImage = LoadImage(blitzmaxPixmap)
Local halflifeImage:TImage = LoadImage(halflifePixmap)
Graphics(800, 600)
    
While Not KeyDown(Key_Escape)
    DrawImage(blitzmaxImage, 0, 0)
    DrawImage(halflifeImage, 200, 0)
            
    Flip
Wend
https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."