P2P Zero-Knowledge-Proof based Opensource Social Network - HexHoot

I find that the domain name that I purchased on an impulse, hexhoot.com, would be the ideal name for the p2p social network; both of which I described in some of my previous posts. I have been working on it during my pasttime for about a month now, and I decided to make it opensource. You can have a look at the project using the following link: https://github.com/zenineasa/hexhoot I have attempted to follow all the best development practices as much as I can. I have written tests, and, enabled continuous integration feature in GitHub to run all the tests, lint and copyright checks for the code changes that is being made. I also have captured all the foreseeable tasks in a Trello dashboard. This helps me keep track of all the bugs that I have detected and all the important tasks that need to be completed. There are quite a lot of tasks left to make this bug-free and feature-rich. I hope I will find enough time and motivation to do the same in the coming days.

da Vinci of the 21st Century

According to many sources, Leonardo Da Vinci is known for hiding secret codes and messages in his art work. In the modern era, digital canvases and images have a greater role to play.

An image of width w and height h contains x h pixels. Changing the RGB values by a small value would not be detectable to naked eye. In this blog post, let me show you how to encrypt and decrypt messages using this principle. We'll do both encryption and decryption using JavaScript.

To get started with, I downloaded a very nice picture of Mona Lisa from Wikipedia (. I also created an image with black text in a white background, which I shall not show here (message.jpg).


Next, I setup a good HTML platform to run back to back JavaScript commands, which would automatically load all the images I need. To avoid CORS issue, I have been running a SimpleHTTPServer to open up the webpage.

<html>
<body>
<img src="725px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg" id="original" style="display: none"/>
<img src="message.jpg" id="message" style="display: none" />
<img src="encryptedTextHere.jpg" id="encrypted" style="display: none" />
<canvas id="myCanvas" width="725" height="1080" style="border:1px solid #d3d3d3;">

<script>

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

</script>
</body>
</html>

Note that encryptedTextHere.jpg does not exist as of now, but that can be ignored. That is the location where I intent to save the encrypted file.

Encrypting


Now that the platform is up, let's open the Chrome Developer Console (press CTRL+Shift+J and click on Console tab). Let us read both the images into canvas image data arrays. Then, in the original Mona Lisa image, wherever the pixels matches with the message image, let us increment the RGB pixels by 1 value. Ignore all the white spaces. The following code takes care of that.



var original = document.getElementById("original");
var message = document.getElementById("message");
ctx.drawImage(original, 0, 0);
var originalArray = ctx.getImageData(0, 0, c.width, c.height);
ctx.drawImage(message, 0, 0);
var messageArray = ctx.getImageData(0, 0, c.width, c.height);
for(var i=0;i<originalArray.data.length;i+=4){
    if(messageArray.data[i] + messageArray.data[i+1] + messageArray.data[i+2] + messageArray.data[i+3] !== 255*4){ // ignoring white
        originalArray.data[i] += 1;
        originalArray.data[i+1] += 1;
        originalArray.data[i+2] += 1;
    }
}
ctx.putImageData(originalArray, 0, 0);
Once the image is drawn, save the image as encryptedTextHere.jpg. You have succesfully encrypted your message into the image. If you observe the image, it is hard (or impossible) to say what message is encrypted with your naked eye.

Decrypting

Both the original image and the encrypted image are required to find the hidden text. Since we just added a pixel at every point where there is a corresponding pixel in the message image existed, we could simply reverse the process to get some value at the pixels where the message existed. To get a better clarity, multiply that with a value of 100. The following code does the same. Leave every fourth pixel (opacity) at the maximum value of 255.



var original = document.getElementById("original");
var encrypted = document.getElementById("encrypted");
ctx.drawImage(original, 0, 0);
var originalArray = ctx.getImageData(0, 0, c.width, c.height);
ctx.drawImage(encrypted, 0, 0);
var encryptedArray = ctx.getImageData(0, 0, c.width, c.height);
for(var i=0;i<originalArray.data.length;i++){
    encryptedArray.data[i] = (encryptedArray.data[i] - originalArray.data[i]) * 100;
    if((i+1)%4 === 0) // transparency part
        encryptedArray.data[i] = 255;
}
ctx.putImageData(encryptedArray, 0, 0);
You now have a pretty neat tool in your hand to encrypt and decrpy messages. You may tweak the technique a bit to store encrypted data in the way you desire. Some things are best kept secrets. Cheers!

Comments

Popular posts from this blog

Regarding a Covid-19 related project that I worked on a few months ago

Went into the University for the first time

P2P Zero-Knowledge-Proof based Opensource Social Network - HexHoot