Instantly share code, notes, and snippets.

anonymous /visual-crypto.js
Created Jan 12, 2018

Embed
What would you like to do?
Visual cryptography using JavaScript
const fs = require('fs');
const PNG = require('pngjs').PNG;
/*
Utilities
=========
*/
const PNG_OPTIONS = {
GRAYSCALE_AND_ALPHA: 4,
FILTER: 4
}
function Pixel(red, green, blue, alpha) {
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = alpha;
return this;
};
// Turn each raw pixel into a keyed RGBA object.
PNG.prototype.toNamedPixels = function() {
const named = [];
for (var y = 0; y < this.height; y++) {
for (var x = 0; x < this.width; x++) {
var idx = (this.width * y + x) << 2;
named.push(new Pixel(
this.data[idx],
this.data[idx + 1],
this.data[idx + 2],
this.data[idx + 3])
);
}
}
return named;
};
// Transform our patterns into coordinates for the output share png.
// This code looks hard but really isn't that important to understand.
// It just copies each pattern into place in the share png.
PNG.prototype.fillFromPatterns = function(patterns) {
var png = this;
for (var y = 0; y < png.height; y++) {
for (var x = 0; x < png.width; x++) {
// Find the pattern for this pixel.
const row = Math.floor(y / 2);
const column = Math.floor(x / 2);
const patternsPerRow = png.width / 2;
const pattern = patterns[row * patternsPerRow + column]
// Now copy the relevant part of the pattern for this subpixel.
const top = y % 2 === 0;
const left = x % 2 === 0;
let part;
if (top && left) {
part = pattern[0];
} else if (top && !left) {
part = pattern[1];
} else if (!top && left) {
part = pattern[2];
} else {
part = pattern[3];
}
const idx = (png.width * y + x) << 2;
png.data[idx] = part.red;
png.data[idx+1] = part.green;
png.data[idx+2] = part.blue;
png.data[idx+3] = part.alpha;
}
}
};
/*
Implementation
==============
*/
const secretStream = fs.createReadStream('burst-secret.png');
const shareOneStream = fs.createWriteStream('burst-share-1.png');
const shareTwoStream = fs.createWriteStream('burst-share-2.png');
const patternA = [
/*
Pattern A
B W
W B
*/
new Pixel(0, 0, 0, 255),
new Pixel(0, 0, 0, 0),
new Pixel(0, 0, 0, 0),
new Pixel(0, 0, 0, 255)
];
const patternB = [
/*
Pattern B
W B
B W
*/
new Pixel(0, 0, 0, 0),
new Pixel(0, 0, 0, 255),
new Pixel(0, 0, 0, 255),
new Pixel(0, 0, 0, 0)
];
// This is the important function -- it's how we encode our shares.
// Given a secret pixel, subdivide it into four subpixels with a set pattern.
const subdivideSecretPixel = (pixel) => {
const redPill = Math.random() > 0.5;
if (pixel.alpha > 0) {
// The pixel is coloured in the secret.
// When overlaid, all four subdivisions in the shares need to be black.
if (redPill) return [ patternA, patternB ];
return [ patternB, patternA ];
}
// The pixel in the secret was not coloured.
// When overlaid, only two of the four subdivisions should be black.
if (redPill) return [patternA, patternA];
return [patternB, patternB];
};
secretStream.pipe(new PNG({
filterType: PNG_OPTIONS.FILTER,
colorType: PNG_OPTIONS.GRAYSCALE_AND_ALPHA
}))
.on('parsed', function() {
const secret = this;
const shareOptions = {
filterType: PNG_OPTIONS.FILTER,
colorType: PNG_OPTIONS.GRAYSCALE_AND_ALPHA,
// We will subdivide each pixel in the secret image into four components.
width: secret.width * 2,
height: secret.height * 2
};
const shareOnePng = new PNG(shareOptions);
const shareTwoPng = new PNG(shareOptions);
const pixels = secret.toNamedPixels();
// This is the key step. Split and encode each pixel into its subdivided components.
const subdivided = pixels.map(subdivideSecretPixel);
const shareOnePatterns = subdivided.map(s => s[0]);
const shareTwoPatterns = subdivided.map(s => s[1]);
// Each pixel in the secret image has been split into four parts for each share.
// Perfecto 👌.
shareOnePng.fillFromPatterns(shareOnePatterns)
shareTwoPng.fillFromPatterns(shareTwoPatterns)
shareOnePng.pack().pipe(shareOneStream);
shareTwoPng.pack().pipe(shareTwoStream);
});
@ankitha19vaddeti

This comment has been minimized.

ankitha19vaddeti commented Oct 11, 2018

can you share your pngjs.js file
my mailid is ankithavaddeti25@gmail.com

@ankitha19vaddeti

This comment has been minimized.

ankitha19vaddeti commented Oct 11, 2018

can you share your fs.js file too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment