Skip to content

Commit 2b530c0

Browse files
committed
update to ScyWeb.html
1 parent 72d5bb0 commit 2b530c0

7 files changed

Lines changed: 122 additions & 15 deletions
320 Bytes
Loading
-203 KB
Loading
26.4 MB
Loading
2.03 MB
Loading

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ An encrypted string of the original image [glacier_og_image_4503x3002.jpg](https
2020

2121
> Encrypted string is 100%+ larger than scrambled image. Difference between fully compressed original image and fully compressed scrambled image is 20%+ larger file size. Viability of scrambling images as a substitute for image to string encryption confirmed.
2222
23+
### Quantum-resistant method
24+
Still under development but color diffusion is present in a unique format and looks to impossible to unscramble using heuristic algorithms.
25+
26+
> Encrypted string is 15%+ larger than scrambled image. Unfortunately, quantum resistant method is not compatible with compression, as it has too many pixel re-replication errors.
27+
28+
#### Success of image scrambling for tailored use cases is high. Unique viable use for making uninterrupted and uncompromised streaming, making a video stream unable to be modified in transit when delivered to users in real-time, offloading costs to user devices when it comes to unscrambling and re-rendering. Other uses include secure Bluerays, DVDs, and new age optical drives. Advanced use cases for movies delivered to theaters to prevent bootlegging. More use cases being tested but the sky is the limit.
2329

2430
## Movie scrambling
2531
Lossless compression is not used on unscrambled movies so the original movie might be much smaller when compared to the new unscrambled movie. Scrambled movies are much bigger in their scrambled form than movies that use pixel information sharing, as this gets lost in the enciphering process. This is an area for further development. It means encrypted movies are smaller in size than scrambled movies. Below is a demo showing image scrambling being used on Big Buck Bunny at 1080 and then being converted back to unscrambled. There is no visual difference between the movies before and after scrambling and unscrambling them.

ScyWeb.html

Lines changed: 116 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@
8282
<button id="hideBtn">Hide Preview</button>
8383
</div>
8484
<div class="opt-row">
85-
<div style="display:flex; gap:5px;"><input type="checkbox" id="modeType"><label for="modeType">Alternate Method</label></div>
85+
<div style="display:flex; gap:5px;"><input type="checkbox" id="modeType"><label for="modeType">Alternative (Compression Compatible)</label></div>
86+
<div style="display:flex; gap:5px;"><input type="checkbox" id="modeType2"><label for="modeType2">Quantum (Compression Incompatible)</label></div>
8687
<div style="display:flex; gap:5px;"><input type="checkbox" id="secureFn"><label for="secureFn">Secure Names</label></div>
8788
<div style="display:flex; gap:5px;"><input type="checkbox" id="autoDl"><label for="autoDl">Auto-Download</label></div>
8889
<div style="display:flex; gap:5px; color:#555;"><input type="checkbox" checked disabled><label>Strip EXIF</label></div>
@@ -117,7 +118,14 @@
117118
const queueList = document.getElementById('queueList'), clearBtn = document.getElementById('clearBtn'), secureFn = document.getElementById('secureFn');
118119
const autoDl = document.getElementById('autoDl'), placeholder = document.getElementById('placeholderText'), auditLog = document.getElementById('auditLog');
119120
const timerDisplay = document.getElementById('timerDisplay'), exportBtn = document.getElementById('exportLogBtn');
120-
const modeType = document.getElementById('modeType');
121+
const modeType = document.getElementById('modeType'), modeType2 = document.getElementById('modeType2');
122+
123+
modeType.addEventListener('change', function() {
124+
modeType2.checked = false;
125+
});
126+
modeType2.addEventListener('change', function() {
127+
modeType.checked = false;
128+
});
121129

122130
let processedFiles = [], destructTime = 300;
123131
var videoFile = null;
@@ -220,21 +228,18 @@
220228
*/
221229

222230
// createPRNG replacement to ensure perfect image unscramble
223-
function createPRNG(seedPhrase) {
224-
let seed = 0;
225-
for (let i = 0; i < seedPhrase.length; i++) {
226-
seed = ((seed << 5) - seed) + seedPhrase.charCodeAt(i);
227-
seed |= 0;
228-
}
231+
function createPRNG(numericSeed) {
232+
let seed = Number(numericSeed % 4294967296n) | 0;
229233
return function() {
230-
seed |= 0; seed = seed + 0x9e3779b9 | 0;
231-
let t = seed ^ seed >>> 16; t = Math.imul(t, 0x21f0aaad);
232-
t = t ^ t >>> 15; t = Math.imul(t, 0x735a2d97);
233-
return ((t = t ^ t >>> 15) >>> 0) / 4294967296;
234+
seed = (seed + 0x9e3779b9) | 0;
235+
let t = seed ^ (seed >>> 16);
236+
t = Math.imul(t, 0x21f0aaad);
237+
t = t ^ (t >>> 15);
238+
t = Math.imul(t, 0x735a2d97);
239+
return ((t = t ^ (t >>> 15)) >>> 0) / 4294967296;
234240
};
235241
}
236242

237-
238243
async function processImage(file, seed, isUnscramble) {
239244
return new Promise((resolve) => {
240245
const reader = new FileReader();
@@ -278,7 +283,7 @@
278283
*/
279284
// new createPRNG implementation to ensure perfect image unscramble
280285
img.onload = async () => {
281-
if(modeType.checked != true){
286+
if(modeType.checked != true && modeType2.checked != true){
282287
// DEFAULT METHOD
283288
// current implementation has pixel perfect re-replication
284289
// the will become the default method with a toggle to allow
@@ -325,7 +330,7 @@
325330
}
326331
logActivity(isUnscramble ? 'Unlocked' : 'Locked', file.name);
327332
resolve();
328-
} else {
333+
} else if (modeType.checked == true && modeType2.checked != true) {
329334
// ALTERNATIVE METHOD
330335
// this implementation does not have pixel perfect re-replication
331336
// and is not a problem with color diffusion, as it represents
@@ -377,6 +382,102 @@
377382

378383
logActivity(isUnscramble ? 'Unlocked' : 'Locked', file.name);
379384
resolve();
385+
} else if (modeType.checked != true && modeType2.checked == true){
386+
// QUANTUM METHOD
387+
// this implementation has near pixel perfect re-replication in most cases
388+
// it represents an entirely different methodology of block-chunking pixels
389+
// it seems to be quantum proof
390+
const tCvs = document.createElement('canvas'), tCtx = tCvs.getContext('2d', {willReadFrequently:true});
391+
tCvs.width = img.width; tCvs.height = img.height;
392+
tCtx.drawImage(img, 0, 0);
393+
const w = img.width, h = img.height;
394+
const block_size = 8;
395+
const cols = Math.ceil(w / block_size);
396+
const rows = Math.ceil(h / block_size);
397+
const numBlocks = cols * rows;
398+
const pixelData = tCtx.getImageData(0, 0, w, h);
399+
const data = pixelData.data;
400+
const getIdx = (x, y) => (Math.min(y, h - 1) * w + Math.min(x, w - 1)) * 4;
401+
const uniqueChunks = [];
402+
const chunkMap = new Int32Array(numBlocks);
403+
const hashMap = new Map();
404+
for (let i = 0; i < numBlocks; i++) {
405+
const by = Math.floor(i / cols) * block_size;
406+
const bx = (i % cols) * block_size;
407+
let key = "";
408+
for (let y = 0; y < block_size; y++) {
409+
for (let x = 0; x < block_size; x++) {
410+
const p = getIdx(bx + x, by + y);
411+
key += data[p] + "," + data[p+1] + "," + data[p+2] + "," + data[p+3] + "|";
412+
}
413+
}
414+
if (!hashMap.has(key)) {
415+
const block = new Uint8ClampedArray(block_size * block_size * 4);
416+
let bIdx = 0;
417+
for (let y = 0; y < block_size; y++) {
418+
for (let x = 0; x < block_size; x++) {
419+
const p = getIdx(bx + x, by + y);
420+
block[bIdx++] = data[p];
421+
block[bIdx++] = data[p+1];
422+
block[bIdx++] = data[p+2];
423+
block[bIdx++] = data[p+3];
424+
}
425+
}
426+
hashMap.set(key, uniqueChunks.length);
427+
uniqueChunks.push(block);
428+
}
429+
chunkMap[i] = hashMap.get(key);
430+
}
431+
const prng = createPRNG(seed);
432+
const shuffleMap = new Int32Array(numBlocks);
433+
for(let i=0; i<numBlocks; i++) shuffleMap[i] = i;
434+
for(let i = numBlocks - 1; i > 0; i--) {
435+
const val = (prng.next ? prng.next().value : prng());
436+
const j = Math.floor(val * (i + 1));
437+
[shuffleMap[i], shuffleMap[j]] = [shuffleMap[j], shuffleMap[i]];
438+
}
439+
const colorPrng = createPRNG(seed);
440+
for (let i = 0; i < numBlocks; i++) {
441+
const srcIdx = isUnscramble ? shuffleMap[i] : i;
442+
const dstIdx = isUnscramble ? i : shuffleMap[i];
443+
const val = (colorPrng.next ? colorPrng.next().value : colorPrng());
444+
const offset = Math.floor(val * 256);
445+
const chunk = uniqueChunks[chunkMap[srcIdx]];
446+
const dy = Math.floor(dstIdx / cols) * block_size;
447+
const dx = (dstIdx % cols) * block_size;
448+
let bIdx = 0;
449+
for (let y = 0; y < block_size; y++) {
450+
for (let x = 0; x < block_size; x++) {
451+
if (dx + x < w && dy + y < h) {
452+
const p = ((dy + y) * w + (dx + x)) * 4;
453+
for (let c = 0; c < 3; c++) {
454+
let original = chunk[bIdx++];
455+
if (!isUnscramble) {
456+
data[p + c] = (original + offset) % 256;
457+
} else {
458+
let result = (original - offset) % 256;
459+
data[p + c] = result < 0 ? result + 256 : result;
460+
}
461+
}
462+
bIdx++;
463+
data[p + 3] = chunk[bIdx - 1];
464+
} else {
465+
bIdx += 4;
466+
}
467+
}
468+
}
469+
if (i % (cols * 10) === 0) await new Promise(r => setTimeout(r, 0));
470+
}
471+
tCtx.putImageData(pixelData, 0, 0);
472+
const resData = tCvs.toDataURL('image/png');
473+
let fn = secureFn.checked ? Math.random().toString(36).substr(2,12)+".png" : (isUnscramble?'dec_':'enc_')+file.name;
474+
processedFiles.push({ name: fn, data: resData });
475+
if(autoDl.checked) { const a = document.createElement('a'); a.download = fn; a.href = resData; a.click(); }
476+
if(upload.files.length === 1) { cvs.width = img.width; cvs.height = img.height; ctx.putImageData(pixelData, 0, 0); cvs.style.display = 'block'; placeholder.style.display = 'none'; }
477+
logActivity(isUnscramble ? 'Unlocked' : 'Locked', file.name);
478+
resolve();
479+
} else {
480+
alert("Please select one mode and try again.");
380481
}
381482
};
382483
// end of new createPRNG implementation
904 KB
Loading

0 commit comments

Comments
 (0)