Skip to content

Commit 32f31e8

Browse files
committed
update to ScyWeb
1 parent 8d1b379 commit 32f31e8

6 files changed

Lines changed: 144 additions & 3 deletions

File tree

ORIGINAL_TEXT_test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a test.

README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# ScyWeb
22
ScyWeb is a lightweight, deployable web application that lets users scramble and unscramble image files from a browser.
33

4+
![ScyWeb Logo](https://raw.githubusercontent.com/mdbench/ScyWeb/master/ScyWebLogo.jpg)
5+
6+
## Working paper
7+
- [Future academic submission as PDF](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/WorkingPaper.pdf)
8+
- [LaTeX submission version](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/WorkingPaper.tex)
9+
410
## Why is it called ScyWeb?
511
A scytale is an ancient Greek transposition cipher that utilizes a rod and parchment to scramble and unscramble messages. ScyWeb was developed to provide an image cipher experience using web technologies.
612

@@ -39,28 +45,43 @@ Important quantum-resistant method metrics have been listed below, showing infea
3945
### Ultra Quantum-resistant method
4046
Ultra quantum-proofing is a new concept where quantum methods cannot decipher or decrypt, even if the universe was a computer. Under the conditions of a simulation and simulacra, it would still be theoretically impossible to decipher or decrypt an ultra quantum scrambled image as long as the password was zero-knowledge or tied to an external process like a black box.
4147

42-
#### 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.
48+
#### Success of image scrambling for tailored use cases is high. Extremely good for private photos. Further use cases below.
4349

4450
## Movie scrambling
4551
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.
4652
- [Demo](https://demos.matthewbenchimol.com/ScyWeb/ScyWebVideoTester.html)
4753
- [Original Big Buck Bunny](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/Big_Buck_Bunny_1080_10s_30MB.mp4)
4854
- [Unscrambled Big Buck Bunny](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/enc_BBB_Unscrambled.mp4)
4955

56+
### Success of movie 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.
57+
5058
## Audio scrambling
5159
The audio scrambling methodology takes an audio file, converts it to an image, and scrambles it using the default mode. It saves the resulting file with an mp3 extension, even though it is an image. When you add the scrambled audio file, unscrambling it, it is a perfect replication of the audio file, allowing you to store music in an encrypted format. Since music is already highly diffuse with high entropy, the default mode is sufficient to make the resulting scrambled audio image ultra quantum proof. This audio methodology also creates a 1:1 file size where the original audio file size is the exact size of the resulting scrambled image. You essentially lose nothing storage wise. Because it is unmodifiable without corrupting the audio image, this means it is impossible to modify your copy of whatever audio file you have.
5260
- [Original MP3 Test File](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/ORIGINAL_AUDIO_solarflex-jazz-cafe-music-509921.mp3)
5361
- [Scrambled MP3 Image with MP3 extension File](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/enc_SCRAMBLED_AUDIO_solarflex-jazz-cafe-music-509921_5287680.mp3)
5462
- [Unscrambled MP3 Image Back to MP3 File](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/dec_UNSCRAMBLED_AUDIO_solarflex-jazz-cafe-music-509921.mp3)
5563

64+
### Success of audio scrambling for tailored use cases is extremely high. iTunes or Spotify could integrate this technology into their current database, making a music database compromise impossible. They could also integrate into their platforms, sending the audio image, coding right-before-use/just-in-time conversion, making music impossible to steal from a cache on all Operating Systems. This methodology would download a quantum proof image as a stable data-dependent cache and decrypt right before use in memory. Likely, trillion $ algorithm use case, as no compression lost.
65+
66+
## Text scrambling
67+
The text scrambling methodology takes a text file (all text/* files supported), converts it to an image, and scrambles it using the default mode. It saves the resulting file with a txt extension, even though it is an image. When you add the scrambled text file, unscrambling it, it is a perfect replication of the text file, allowing you to store text files in an encrypted format. Since text is already highly diffuse with high entropy, the default mode is sufficient to make the resulting scrambled text image ultra quantum proof. Unfortunately, this text methodology creates text files that are bigger than the originals.
68+
- [Original TXT Test File](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/ORIGINAL_TEXT_test.txt)
69+
- [Scrambled TXT Image with TXT extension File](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/enc_SCRAMBLED_TEXT_test.txt_16.txt)
70+
- [Unscrambled TXT Image Back to TXT File](https://raw.githubusercontent.com/mdbench/ScyWeb/refs/heads/main/dec_UNSCRAMBLED_TEXT__test.txt)
71+
72+
### Success of text scrambling for tailored use cases is high. Storing text files as pictures could be used for website code files, rendered to user which then JS decrypts dynamically. Quantum resistant websites edited offline and uploaded as pictures render HTTPS and future web technologies obsolete. Website compromise would be meaningless without password, even if hacker got access to source code. Even passwords can be sent as pictures, making them impossible to steal with taffic sniffers, even if website was HTTP.
73+
5674
## Due-Outs
5775
- Fix pixel re-replication issue for fully compressed images on alternative method
5876
- Severity: Low
5977
- Fix pixel re-replication issue for fully compressed images on quantum method
6078
- Severity: High
6179
- Add bulk image download for all files as a .zip option
80+
- Improve User Interface (UI) for Desktop/Mobile devices
6281
- Integrate image scrambling into HelioWeb
6382
- Integrate music scrambling into PhonoWeb
83+
- Calculate $ amount this project could earn
84+
- Apply for patents (share patent numbers here)
6485

6586
## Want to contribute?
6687
Send me a pull request.

ScyWeb.html

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@
7676
<!-- Vault View -->
7777
<div id="vaultView" class="view-content active">
7878
<div class="controls">
79-
<label>1. Select Image(s), Video, or Audio</label>
80-
<input type="file" id="upload" accept="image/*, video/*, audio/*" multiple>
79+
<label>1. Select Image(s), Video, Audio, or Text</label>
80+
<input type="file" id="upload" accept="image/*, video/*, audio/*, text/*" multiple>
8181
<label>2. Settings</label>
8282
<div class="btn-group">
8383
<input type="password" id="password" placeholder="Secret phrase..." autocomplete="off">
@@ -140,6 +140,7 @@
140140
let processedFiles = [], destructTime = 300;
141141
var videoFile = null;
142142
var audioFile = null;
143+
var textFile = null;
143144

144145
function switchTab(view) {
145146
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
@@ -193,6 +194,9 @@
193194
};
194195

195196
upload.onchange = async (e) => {
197+
videoFile = null;
198+
audioFile = null;
199+
textFile = null;
196200
const files = e.target.files;
197201
if (files.length === 1) {
198202
const mimeType = files[0].type;
@@ -213,6 +217,8 @@
213217
videoFile = files[0];
214218
} else if (mimeType.startsWith('audio/')) {
215219
audioFile = files[0];
220+
} else if (mimeType.startsWith('text/')) {
221+
textFile = files[0];
216222
}
217223
} else {
218224
cvs.style.display = 'none'; placeholder.style.display = 'block';
@@ -627,6 +633,8 @@
627633
await processVideo(videoFile, 30, seed, isUnscramble);
628634
} else if (audioFile != null) {
629635
await processAudio(audioFile, seed, isUnscramble);
636+
} else if (textFile != null) {
637+
await processText(textFile, seed, isUnscramble);
630638
} else {
631639
const files = upload.files;
632640
if (!files.length) return alert("Select files first.");
@@ -903,6 +911,116 @@
903911
setTimeout(() => { if(document.body.contains(loader)) document.body.removeChild(loader); }, 1000);
904912
}
905913
}
914+
915+
// text functions
916+
async function processText(file, seed = "", isUnscramble = false) {
917+
const loader = document.createElement('div');
918+
Object.assign(loader.style, {
919+
position: 'fixed', top: '0', left: '0', width: '100%', height: '100%',
920+
backgroundColor: 'rgba(0,0,0,0.95)', color: 'white', display: 'flex',
921+
flexDirection: 'column', alignItems: 'center', justifyContent: 'center', zIndex: '10000'
922+
});
923+
loader.innerHTML = `<p id="st">Processing Masquerade...</p>`;
924+
document.body.appendChild(loader);
925+
try {
926+
if (!isUnscramble) {
927+
const originalFullName = file.name;
928+
const arrayBuffer = await file.arrayBuffer();
929+
const fileBytes = new Uint8Array(arrayBuffer);
930+
const originalSize = fileBytes.length;
931+
const totalPixels = Math.ceil(originalSize / 3);
932+
const side = Math.ceil(Math.sqrt(totalPixels));
933+
const canvas = document.createElement('canvas');
934+
canvas.width = side; canvas.height = side;
935+
const ctx = canvas.getContext('2d', { colorSpace: 'srgb', alpha: false });
936+
const imageData = ctx.createImageData(side, side);
937+
const data = imageData.data;
938+
let fIdx = 0;
939+
for (let i = 0; i < data.length; i += 4) {
940+
data[i] = fIdx < originalSize ? fileBytes[fIdx++] : 0;
941+
data[i + 1] = fIdx < originalSize ? fileBytes[fIdx++] : 0;
942+
data[i + 2] = fIdx < originalSize ? fileBytes[fIdx++] : 0;
943+
data[i + 3] = 255;
944+
}
945+
// DEFAULT METHOD
946+
// because text files are already high entropy and high diffusion
947+
// a simply fisher-yates shuffle is sufficient to make it ultra quantum resistant
948+
const len = side * side;
949+
const prng = createPRNG(seed);
950+
const map = new Int32Array(len);
951+
for(let i=0; i<len; i++) map[i] = i;
952+
for(let i=len-1; i>0; i--) {
953+
const j = Math.floor((prng.next ? prng.next().value : prng()) * (i + 1));
954+
[map[i], map[j]] = [map[j], map[i]];
955+
}
956+
const tempData = new Uint8ClampedArray(data);
957+
for(let i=0; i<len; i++) {
958+
const s = i * 4;
959+
const d = map[i] * 4;
960+
data[d] = tempData[s];
961+
data[d + 1] = tempData[s + 1];
962+
data[d + 2] = tempData[s + 2];
963+
data[d + 3] = 255;
964+
}
965+
ctx.putImageData(imageData, 0, 0);
966+
canvas.toBlob((blob) => {
967+
const a = document.createElement('a');
968+
a.href = URL.createObjectURL(blob);
969+
// some meta data in filename cannot be changed
970+
// that means do not change text filenames!
971+
a.download = `enc_${originalFullName}_${originalSize}.txt`;
972+
a.click();
973+
}, 'image/png');
974+
975+
} else {
976+
const metaMatch = file.name.match(/^enc_(.+)_(\d+)\.txt$/);
977+
if (!metaMatch) throw new Error("Format Error: File must be named enc_FILENAME_SIZE.txt");
978+
const originalName = metaMatch[1];
979+
const originalSize = parseInt(metaMatch[2]);
980+
const img = new Image();
981+
img.src = URL.createObjectURL(file);
982+
await new Promise(r => img.onload = r);
983+
const canvas = document.createElement('canvas');
984+
canvas.width = img.width; canvas.height = img.height;
985+
const ctx = canvas.getContext('2d', { colorSpace: 'srgb', alpha: false });
986+
ctx.drawImage(img, 0, 0);
987+
const data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
988+
const len = canvas.width * canvas.height;
989+
const prng = createPRNG(seed);
990+
const map = new Int32Array(len);
991+
for(let i=0; i<len; i++) map[i] = i;
992+
for(let i=len-1; i>0; i--) {
993+
const j = Math.floor((prng.next ? prng.next().value : prng()) * (i + 1));
994+
[map[i], map[j]] = [map[j], map[i]];
995+
}
996+
const tempData = new Uint8ClampedArray(data);
997+
const unscrambledData = new Uint8ClampedArray(data.length);
998+
for(let i=0; i<len; i++) {
999+
const s = map[i] * 4;
1000+
const d = i * 4;
1001+
unscrambledData[d] = tempData[s];
1002+
unscrambledData[d + 1] = tempData[s + 1];
1003+
unscrambledData[d + 2] = tempData[s + 2];
1004+
}
1005+
const recoveredBytes = new Uint8Array(originalSize);
1006+
let rIdx = 0;
1007+
for (let i = 0; i < unscrambledData.length && rIdx < originalSize; i += 4) {
1008+
recoveredBytes[rIdx++] = unscrambledData[i];
1009+
if (rIdx < originalSize) recoveredBytes[rIdx++] = unscrambledData[i+1];
1010+
if (rIdx < originalSize) recoveredBytes[rIdx++] = unscrambledData[i+2];
1011+
}
1012+
const finalBlob = new Blob([recoveredBytes]);
1013+
const a = document.createElement('a');
1014+
a.href = URL.createObjectURL(finalBlob);
1015+
a.download = `dec_${originalName}`;
1016+
a.click();
1017+
}
1018+
} catch (e) {
1019+
alert("Masquerade Restoration Error: " + e.message);
1020+
} finally {
1021+
setTimeout(() => { if(document.body.contains(loader)) document.body.removeChild(loader); }, 1000);
1022+
}
1023+
}
9061024

9071025
// analytical functions
9081026
function analyzeCanvasImage() {

ScyWebLogo.jpg

87.7 KB
Loading

dec_UNSCRAMBLED_TEXT__test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a test.

enc_SCRAMBLED_TEXT_test.txt_16.txt

114 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)