mirror of
https://github.com/planetrenox/inzerosight.git
synced 2026-09-18 10:05:44 +00:00
feat: in-page detection with overlay UI and 5-char signatures
This commit is contained in:
215
content.js
Normal file
215
content.js
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
import zwus from 'zwus';
|
||||||
|
import * as speck48_96ctr from './speck48_96ctr.js';
|
||||||
|
import * as speck32_64ecb from './speck32_64ecb.js';
|
||||||
|
import { SIG_PREFIX, parseSig, getPayloadEnd } from './sig.js';
|
||||||
|
|
||||||
|
let host, shadow;
|
||||||
|
const active = new Set();
|
||||||
|
|
||||||
|
function initShadow() {
|
||||||
|
if (host) return;
|
||||||
|
host = document.createElement('div');
|
||||||
|
host.id = 'in0-host';
|
||||||
|
shadow = host.attachShadow({ mode: 'open' });
|
||||||
|
const s = document.createElement('style');
|
||||||
|
s.textContent = `
|
||||||
|
.in0-wrap {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: auto;
|
||||||
|
z-index: 2147483647;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
font-family: system-ui, -apple-system, sans-serif;
|
||||||
|
}
|
||||||
|
.in0-btn {
|
||||||
|
background: #18191c;
|
||||||
|
color: #fff;
|
||||||
|
border: 1px solid #3a3b40;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 4px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.5);
|
||||||
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.in0-btn:hover {
|
||||||
|
border-color: #00b4d8;
|
||||||
|
box-shadow: 0 0 8px rgba(0,180,216,0.4);
|
||||||
|
}
|
||||||
|
.in0-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -6px;
|
||||||
|
right: -6px;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #00b4d8;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
.in0-arrow {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 5px solid transparent;
|
||||||
|
border-right: 5px solid transparent;
|
||||||
|
border-top: 6px solid #18191c;
|
||||||
|
margin-top: -1px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
shadow.appendChild(s);
|
||||||
|
(document.body || document.documentElement).appendChild(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createOverlay(node, parsed, start, end) {
|
||||||
|
initShadow();
|
||||||
|
const wrap = document.createElement('div');
|
||||||
|
wrap.className = 'in0-wrap';
|
||||||
|
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.className = 'in0-btn';
|
||||||
|
btn.textContent = parsed.cipher === 'PLAIN' ? 'Decode' : 'Decrypt';
|
||||||
|
|
||||||
|
const badge = document.createElement('span');
|
||||||
|
badge.className = 'in0-badge';
|
||||||
|
badge.textContent = '\u00D8';
|
||||||
|
btn.appendChild(badge);
|
||||||
|
|
||||||
|
const arrow = document.createElement('div');
|
||||||
|
arrow.className = 'in0-arrow';
|
||||||
|
|
||||||
|
wrap.appendChild(btn);
|
||||||
|
wrap.appendChild(arrow);
|
||||||
|
shadow.appendChild(wrap);
|
||||||
|
|
||||||
|
const entry = { wrap, node, start, end };
|
||||||
|
active.add(entry);
|
||||||
|
|
||||||
|
btn.onclick = () => onAction(entry, parsed);
|
||||||
|
updatePos(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePos(entry) {
|
||||||
|
const { wrap, node, start, end } = entry;
|
||||||
|
if (!node.isConnected) {
|
||||||
|
wrap.remove();
|
||||||
|
active.delete(entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const r = document.createRange();
|
||||||
|
try {
|
||||||
|
r.setStart(node, start);
|
||||||
|
r.setEnd(node, Math.min(end, node.nodeValue.length));
|
||||||
|
} catch {
|
||||||
|
wrap.remove();
|
||||||
|
active.delete(entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let rect = r.getBoundingClientRect();
|
||||||
|
if (!rect.width && !rect.height && node.parentElement) {
|
||||||
|
rect = node.parentElement.getBoundingClientRect();
|
||||||
|
}
|
||||||
|
const x = rect.left + window.scrollX + (rect.width || 0) / 2;
|
||||||
|
const y = rect.top + window.scrollY;
|
||||||
|
wrap.style.left = `${x - wrap.offsetWidth / 2}px`;
|
||||||
|
wrap.style.top = `${y - wrap.offsetHeight - 2}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAction(entry, parsed) {
|
||||||
|
const { wrap, node, start, end } = entry;
|
||||||
|
const rawPayload = node.nodeValue.slice(start + parsed.sigLen, end);
|
||||||
|
let decoded = '';
|
||||||
|
|
||||||
|
if (parsed.cipher === 'PLAIN') {
|
||||||
|
try {
|
||||||
|
decoded = zwus.decodeToString(rawPayload, parsed.base);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const pass = prompt(`in\u00D8sight: enter password (${parsed.cipher}):`);
|
||||||
|
if (!pass) return;
|
||||||
|
try {
|
||||||
|
const arr = zwus.decodeToNumberArray(rawPayload, parsed.base);
|
||||||
|
if (parsed.cipher === 'SPECK48_96CTR')
|
||||||
|
decoded = speck48_96ctr.decrypt(arr, speck48_96ctr.getKey(pass));
|
||||||
|
else if (parsed.cipher === 'SPECK32_64ECB (insecure)')
|
||||||
|
decoded = speck32_64ecb.decrypt(arr, speck32_64ecb.getKey(pass));
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
if (!decoded) {
|
||||||
|
alert('Decryption failed.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoded) {
|
||||||
|
const r = document.createRange();
|
||||||
|
r.setStart(node, start);
|
||||||
|
r.setEnd(node, end);
|
||||||
|
r.deleteContents();
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.className = 'inzerosight-decoded';
|
||||||
|
span.style.color = '#00b4d8';
|
||||||
|
span.style.fontWeight = '600';
|
||||||
|
span.textContent = ` ${decoded} `;
|
||||||
|
r.insertNode(span);
|
||||||
|
wrap.remove();
|
||||||
|
active.delete(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const scanned = new WeakSet();
|
||||||
|
|
||||||
|
function scanNode(node) {
|
||||||
|
if (!node || node.nodeType !== Node.TEXT_NODE || scanned.has(node)) return;
|
||||||
|
const val = node.nodeValue;
|
||||||
|
if (!val || !val.includes(SIG_PREFIX)) return;
|
||||||
|
|
||||||
|
scanned.add(node);
|
||||||
|
let idx = 0;
|
||||||
|
while (idx < val.length) {
|
||||||
|
const sub = val.slice(idx);
|
||||||
|
const p = parseSig(sub);
|
||||||
|
if (!p) break;
|
||||||
|
const start = idx + p.sigIdx;
|
||||||
|
const end = getPayloadEnd(val, p.base, start + p.sigLen);
|
||||||
|
createOverlay(node, p, start, end);
|
||||||
|
idx = end + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function scanTree(root) {
|
||||||
|
if (!root) return;
|
||||||
|
const ign = { SCRIPT: 1, STYLE: 1, TEXTAREA: 1, INPUT: 1, NOSCRIPT: 1, 'IN0-HOST': 1 };
|
||||||
|
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
||||||
|
acceptNode: n => (ign[n.parentElement?.tagName] ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT)
|
||||||
|
});
|
||||||
|
let n;
|
||||||
|
while ((n = walker.nextNode())) scanNode(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
scanTree(document.body);
|
||||||
|
|
||||||
|
const obs = new MutationObserver(muts => {
|
||||||
|
for (const m of muts) {
|
||||||
|
if (m.type === 'characterData') scanNode(m.target);
|
||||||
|
else for (const an of m.addedNodes) {
|
||||||
|
if (an.nodeType === Node.TEXT_NODE) scanNode(an);
|
||||||
|
else if (an.nodeType === Node.ELEMENT_NODE && an.id !== 'in0-host') scanTree(an);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
obs.observe(document.documentElement, { childList: true, subtree: true, characterData: true });
|
||||||
|
|
||||||
|
window.addEventListener('scroll', () => active.forEach(updatePos), { passive: true });
|
||||||
|
window.addEventListener('resize', () => active.forEach(updatePos), { passive: true });
|
||||||
28
dash.js
28
dash.js
@@ -1,6 +1,7 @@
|
|||||||
import zwus from 'zwus';
|
import zwus from 'zwus';
|
||||||
import * as speck48_96ctr from './speck48_96ctr.js';
|
import * as speck48_96ctr from './speck48_96ctr.js';
|
||||||
import * as speck32_64ecb from './speck32_64ecb.js';
|
import * as speck32_64ecb from './speck32_64ecb.js';
|
||||||
|
import { makeSig, parseSig } from './sig.js';
|
||||||
|
|
||||||
const textarea = document.getElementById('textarea');
|
const textarea = document.getElementById('textarea');
|
||||||
const encoderDropdown = document.getElementById('encoder');
|
const encoderDropdown = document.getElementById('encoder');
|
||||||
@@ -8,12 +9,6 @@ const cipherDropdown = document.getElementById('cipher');
|
|||||||
const signBtn = document.getElementById('sign');
|
const signBtn = document.getElementById('sign');
|
||||||
const sigDetect = document.getElementById('sigDetect');
|
const sigDetect = document.getElementById('sigDetect');
|
||||||
|
|
||||||
const SIG = {
|
|
||||||
3: '\u{200D}\u{200B}\u{00AD}\u{180E}',
|
|
||||||
6: '\u{200D}\u{200B}\u{00AD}\u{2060}',
|
|
||||||
8: '\u{200D}\u{200B}\u{00AD}\u{FEFF}'
|
|
||||||
};
|
|
||||||
|
|
||||||
document.getElementById('encodeButton').addEventListener('click', ACT);
|
document.getElementById('encodeButton').addEventListener('click', ACT);
|
||||||
document.getElementById('decodeButton').addEventListener('click', ACT);
|
document.getElementById('decodeButton').addEventListener('click', ACT);
|
||||||
signBtn.addEventListener('click', e =>
|
signBtn.addEventListener('click', e =>
|
||||||
@@ -32,23 +27,28 @@ function ACT(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const op = event.target.id === 'encodeButton' ? 'NO' : 'YES';
|
const op = event.target.id === 'encodeButton' ? 'NO' : 'YES';
|
||||||
const cipher = getCipherKey();
|
let cipher = getCipherKey();
|
||||||
let base = encoderDropdown.value.split('-')[1];
|
let base = encoderDropdown.value.split('-')[1];
|
||||||
let text = textarea.value;
|
let text = textarea.value;
|
||||||
|
|
||||||
if (op === 'YES') {
|
if (op === 'YES') {
|
||||||
const sigBase = Object.keys(SIG).find(b => text.includes(SIG[b]));
|
const parsed = parseSig(text);
|
||||||
if (sigBase) {
|
if (parsed) {
|
||||||
if (sigBase !== base) {
|
if (parsed.base !== base || (parsed.cipher && parsed.cipher !== cipher)) {
|
||||||
sigDetect.textContent = `ZWUS-${sigBase} signature detected`;
|
const desc = parsed.cipher && parsed.cipher !== 'PLAIN' ? ` (${parsed.cipher})` : '';
|
||||||
|
sigDetect.textContent = `ZWUS-${parsed.base}${desc} signature detected`;
|
||||||
sigDetect.className = 'show';
|
sigDetect.className = 'show';
|
||||||
fadeTimer = setTimeout(() =>
|
fadeTimer = setTimeout(() =>
|
||||||
sigDetect.className = '', 2000
|
sigDetect.className = '', 2000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
base = sigBase;
|
base = parsed.base;
|
||||||
encoderDropdown.value = 'ZWUS-' + base;
|
encoderDropdown.value = 'ZWUS-' + base;
|
||||||
text = text.replace(SIG[base], '');
|
if (parsed.cipher) {
|
||||||
|
cipher = parsed.cipher;
|
||||||
|
cipherDropdown.value = cipher;
|
||||||
|
}
|
||||||
|
text = text.slice(0, parsed.sigIdx) + parsed.payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ function ACT(event) {
|
|||||||
try {
|
try {
|
||||||
let val = DESCRY[op][cipher](text, base, kStr);
|
let val = DESCRY[op][cipher](text, base, kStr);
|
||||||
if (op === 'NO' && signBtn.classList.contains('on'))
|
if (op === 'NO' && signBtn.classList.contains('on'))
|
||||||
val = SIG[base] + val;
|
val = makeSig(base, cipher) + val;
|
||||||
textarea.value = val;
|
textarea.value = val;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
|||||||
54
dist/chrome/content.js
vendored
Normal file
54
dist/chrome/content.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
dist/chrome/index.js
vendored
8
dist/chrome/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/chrome/manifest.json
vendored
2
dist/chrome/manifest.json
vendored
@@ -1 +1 @@
|
|||||||
{"name":"inØsight","version":"2.2.1","author":"planetrenox@pm.me","homepage_url":"https://github.com/planetrenox/inzerosight","description":"Communicate undetected in plain sight.","icons":{"48":"icon_500.png"},"manifest_version":3,"action":{"default_icon":{"48":"icon_500.png"},"default_title":"inØsight","default_popup":"index.html"}}
|
{"name":"inØsight","version":"2.2.1","author":"planetrenox@pm.me","homepage_url":"https://github.com/planetrenox/inzerosight","description":"Communicate undetected in plain sight.","icons":{"48":"icon_500.png"},"manifest_version":3,"action":{"default_icon":{"48":"icon_500.png"},"default_title":"inØsight","default_popup":"index.html"},"content_scripts":[{"matches":["<all_urls>"],"js":["content.js"],"run_at":"document_idle"}]}
|
||||||
54
dist/firefox/content.js
vendored
Normal file
54
dist/firefox/content.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
dist/firefox/index.css
vendored
2
dist/firefox/index.css
vendored
@@ -1 +1 @@
|
|||||||
@font-face{font-family:Open Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/open-sans-v44-latin-regular.woff2) format("woff2")}html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{font-family:Open Sans,sans-serif;background-color:#002b4d;width:500px;height:320px;line-height:1;border:1.5px solid rgb(0,126,199)}#overbar{position:relative;padding:1.5%;font-size:10px;font-weight:700;margin-bottom:0;color:#e5f4ff99;border-bottom:1px solid rgb(0,126,199,.5)}#sigDetect{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-weight:400;color:#e5f4ffd9;opacity:0;transition:opacity 1s}#sigDetect.show{opacity:1;transition:none}#homepage{position:fixed;text-decoration:none;color:#ff0;right:2.5%}#textarea{background-color:#e6e6e6;margin:1.5%;width:95.5%;height:69%;font-family:Open Sans,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;line-height:20px}input{font-size:11.5px}#encodeButton{display:inline-block;margin-bottom:0;margin-left:1.5%;color:#002b4d;cursor:pointer}#decodeButton{margin-bottom:0;margin-left:1.5%;color:#002b4d;cursor:pointer}select{display:inline-block;margin-bottom:0;margin-left:1.5%;color:#002b4d;background-color:#e6e6e6;text-align:center;font-size:11px;width:8em;vertical-align:middle}#encodeButton,#decodeButton{vertical-align:middle}#sign{margin-left:1.5%;font-size:11px;padding:1px 8px;border-radius:99px;border:1px solid rgba(229,244,255,.2);background:transparent;color:#e5f4ff59;cursor:pointer;vertical-align:middle}#sign:hover{border-color:#e5f4ff59;color:#e5f4ff80}#sign.on{background:#e6e6e6;border-color:#e6e6e6;color:#002b4d}#sign.on:hover{background:#fff;border-color:#fff}#notice{font-size:10px;margin-top:1.5%;padding:.8% 0% 0% 1.7%;color:#e5f4ff99;border-top:1px solid rgb(0,126,199,.5)}#versions{color:#007ec7;text-decoration:none}
|
@font-face{font-family:Open Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/open-sans-v44-latin-regular.woff2) format("woff2")}html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{font-family:Open Sans,sans-serif;background-color:#002b4d;width:500px;height:320px;line-height:1;border:1.5px solid rgb(0,126,199)}#overbar{position:relative;padding:1.5%;font-size:10px;font-weight:700;margin-bottom:0;color:#e5f4ff99;border-bottom:1px solid rgb(0,126,199,.5)}#sigDetect{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-weight:400;color:#e5f4ffd9;opacity:0;transition:opacity 1s}#sigDetect.show{opacity:1;transition:opacity .2s}#homepage{position:fixed;text-decoration:none;color:#ff0;right:2.5%}#textarea{background-color:#e6e6e6;margin:1.5%;width:95.5%;height:69%;font-family:Open Sans,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;line-height:20px}input{font-size:11.5px}#encodeButton{display:inline-block;margin-bottom:0;margin-left:1.5%;color:#002b4d;cursor:pointer}#decodeButton{margin-bottom:0;margin-left:1.5%;color:#002b4d;cursor:pointer}select{display:inline-block;margin-bottom:0;margin-left:1.5%;color:#002b4d;background-color:#e6e6e6;text-align:center;font-size:11px;width:8em;vertical-align:middle}#encodeButton,#decodeButton{vertical-align:middle}#sign{margin-left:1.5%;font-size:11px;padding:1px 8px;border-radius:99px;border:1px solid rgba(229,244,255,.2);background:transparent;color:#e5f4ff59;cursor:pointer;vertical-align:middle}#sign:hover{border-color:#e5f4ff59;color:#e5f4ff80}#sign.on{background:#e6e6e6;border-color:#e6e6e6;color:#002b4d}#sign.on:hover{background:#fff;border-color:#fff}#notice{font-size:10px;margin-top:1.5%;padding:.8% 0% 0% 1.7%;color:#e5f4ff99;border-top:1px solid rgb(0,126,199,.5)}#versions{color:#007ec7;text-decoration:none}
|
||||||
|
|||||||
8
dist/firefox/index.js
vendored
8
dist/firefox/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/firefox/manifest.json
vendored
2
dist/firefox/manifest.json
vendored
@@ -1 +1 @@
|
|||||||
{"name":"inØsight","version":"2.2.1","author":"planetrenox@pm.me","homepage_url":"https://github.com/planetrenox/inzerosight","description":"Communicate undetected in plain sight.","icons":{"48":"icon_500.png"},"manifest_version":2,"browser_action":{"browser_style":false,"default_icon":"icon_500.png","default_title":"inØsight","default_popup":"index.html"},"content_security_policy":"script-src 'self'; style-src 'self';","browser_specific_settings":{"gecko":{"id":"{0a73f41c-c59c-404b-9e07-f7392fa830d4}"}}}
|
{"name":"inØsight","version":"2.2.1","author":"planetrenox@pm.me","homepage_url":"https://github.com/planetrenox/inzerosight","description":"Communicate undetected in plain sight.","icons":{"48":"icon_500.png"},"manifest_version":2,"browser_action":{"browser_style":false,"default_icon":"icon_500.png","default_title":"inØsight","default_popup":"index.html"},"content_security_policy":"script-src 'self'; style-src 'self';","browser_specific_settings":{"gecko":{"id":"{0a73f41c-c59c-404b-9e07-f7392fa830d4}"}},"content_scripts":[{"matches":["<all_urls>"],"js":["content.js"],"run_at":"document_idle"}]}
|
||||||
4
dist/web/assets/index-CZZybJ_s.js
vendored
4
dist/web/assets/index-CZZybJ_s.js
vendored
File diff suppressed because one or more lines are too long
4
dist/web/assets/index-wRI3Wnct.js
vendored
Normal file
4
dist/web/assets/index-wRI3Wnct.js
vendored
Normal file
File diff suppressed because one or more lines are too long
64
dist/web/index.html
vendored
64
dist/web/index.html
vendored
@@ -1,33 +1,33 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<script type="module" crossorigin src="/assets/index-CZZybJ_s.js"></script>
|
|
||||||
<script type="module" crossorigin src="/assets/index-wRI3Wnct.js"></script>
|
<script type="module" crossorigin src="/assets/index-wRI3Wnct.js"></script>
|
||||||
</head>
|
<link rel="stylesheet" crossorigin href="/assets/index-DbbumV8Y.css">
|
||||||
<body>
|
</head>
|
||||||
<div id="overbar"><p>inØsight 2.2.1<span id="sigDetect"></span><a id="homepage" href="https://github.com/planetrenox/inzerosight" target="_blank" rel="noopener">source</a></p></div>
|
<body>
|
||||||
<textarea id="textarea" placeholder="input text here..."></textarea>
|
<div id="overbar"><p>inØsight 2.2.1<span id="sigDetect"></span><a id="homepage" href="https://github.com/planetrenox/inzerosight" target="_blank" rel="noopener">source</a></p></div>
|
||||||
<input id="encodeButton" type="button" name="button" value="encode to clipboard"/>
|
<textarea id="textarea" placeholder="input text here..."></textarea>
|
||||||
<input id="decodeButton" type="button" name="button" value="decode from text"/>
|
<input id="encodeButton" type="button" name="button" value="encode to clipboard"/>
|
||||||
<select id="encoder">
|
<input id="decodeButton" type="button" name="button" value="decode from text"/>
|
||||||
<optgroup label="Standard">
|
<select id="encoder">
|
||||||
<option>ZWUS-3</option>
|
<optgroup label="Standard">
|
||||||
<option>ZWUS-6</option>
|
<option>ZWUS-3</option>
|
||||||
<option>ZWUS-8</option>
|
<option>ZWUS-6</option>
|
||||||
</optgroup>
|
<option>ZWUS-8</option>
|
||||||
</select>
|
</optgroup>
|
||||||
<select id="cipher">
|
</select>
|
||||||
<optgroup label="Encryption">
|
<select id="cipher">
|
||||||
<option>PLAIN</option>
|
<optgroup label="Encryption">
|
||||||
<option>SPECK48_96CTR</option>
|
<option>PLAIN</option>
|
||||||
<option>SPECK32_64ECB (insecure)</option>
|
<option>SPECK48_96CTR</option>
|
||||||
</optgroup>
|
<option>SPECK32_64ECB (insecure)</option>
|
||||||
</select>
|
</optgroup>
|
||||||
<button id="sign" type="button" class="on">Sign</button>
|
</select>
|
||||||
<p id="notice">
|
<button id="sign" type="button" class="on">Sign</button>
|
||||||
notice: some platforms restrict Ø width characters.
|
<p id="notice">
|
||||||
</p>
|
notice: some platforms restrict Ø width characters.
|
||||||
</body>
|
</p>
|
||||||
</html>
|
|
||||||
|
|||||||
53
sig.js
Normal file
53
sig.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import zwus from 'zwus';
|
||||||
|
|
||||||
|
export const SIG_PREFIX = '\u{200D}\u{200B}\u{00AD}';
|
||||||
|
|
||||||
|
export const SIG = {
|
||||||
|
3: '\u{200D}\u{200B}\u{00AD}\u{180E}\u{200D}',
|
||||||
|
6: '\u{200D}\u{200B}\u{00AD}\u{200C}\u{200D}',
|
||||||
|
8: '\u{200D}\u{200B}\u{00AD}\u{200C}\u{200C}'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CIPHERS = {
|
||||||
|
1: 'SPECK48_96CTR',
|
||||||
|
2: 'SPECK32_64ECB (insecure)'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CIPHER_TO_ID = Object.fromEntries(
|
||||||
|
Object.entries(CIPHERS).map(([k, v]) => [v, +k])
|
||||||
|
);
|
||||||
|
|
||||||
|
export function makeSig(base, cipher) {
|
||||||
|
let s = SIG[base];
|
||||||
|
const id = CIPHER_TO_ID[cipher];
|
||||||
|
if (id) {
|
||||||
|
const zwDigits = Array.from(id.toString(base).padStart(3, '0'), d => zwus[base][d]).join('');
|
||||||
|
s += zwus[base].unifier + zwus[base][0] + zwDigits;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseSig(text) {
|
||||||
|
if (!text.includes(SIG_PREFIX)) return null;
|
||||||
|
const base = Object.keys(SIG).find(b => text.includes(SIG[b]));
|
||||||
|
if (!base) return null;
|
||||||
|
const sigIdx = text.indexOf(SIG[base]);
|
||||||
|
const after = text.slice(sigIdx + SIG[base].length);
|
||||||
|
const barrier = zwus[base].unifier + zwus[base][0];
|
||||||
|
if (after.startsWith(barrier)) {
|
||||||
|
const zwDigits = Array.from(after.slice(barrier.length, barrier.length + 3));
|
||||||
|
const digits = zwDigits.map(z => Object.keys(zwus[base]).find(k => zwus[base][k] === z)).join('');
|
||||||
|
const cipher = CIPHERS[parseInt(digits, base)];
|
||||||
|
const payload = after.slice(barrier.length + 3);
|
||||||
|
const sigLen = SIG[base].length + barrier.length + 3;
|
||||||
|
return { base, cipher, payload, sigIdx, sigLen };
|
||||||
|
}
|
||||||
|
return { base, cipher: 'PLAIN', payload: after, sigIdx, sigLen: SIG[base].length };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPayloadEnd(text, base, startOffset) {
|
||||||
|
const zw = new Set(Object.values(zwus[base]));
|
||||||
|
let i = startOffset;
|
||||||
|
while (i < text.length && zw.has(text[i])) i++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
@@ -19,6 +19,12 @@ export default defineConfig(async ({ mode }) => {
|
|||||||
icons: { "48": "icon_500.png" },
|
icons: { "48": "icon_500.png" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const content_scripts = [{
|
||||||
|
matches: ["<all_urls>"],
|
||||||
|
js: ["content.js"],
|
||||||
|
run_at: "document_idle"
|
||||||
|
}];
|
||||||
|
|
||||||
if (target === 'chrome') {
|
if (target === 'chrome') {
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
@@ -28,6 +34,7 @@ export default defineConfig(async ({ mode }) => {
|
|||||||
default_title: "in\u00D8sight",
|
default_title: "in\u00D8sight",
|
||||||
default_popup: "index.html",
|
default_popup: "index.html",
|
||||||
},
|
},
|
||||||
|
content_scripts,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +53,7 @@ export default defineConfig(async ({ mode }) => {
|
|||||||
id: "{0a73f41c-c59c-404b-9e07-f7392fa830d4}",
|
id: "{0a73f41c-c59c-404b-9e07-f7392fa830d4}",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
content_scripts,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user