- Neues Schluesselmodell: pro Beziehung zwei Stroeme (send.key/recv.key), Sende-Offset lebt im Schluessel-Header und wird beim Senden fortgeschrieben. Loest two-time-pad bei bidirektionaler Nutzung deterministisch. - Stream-Identifier im Bild -> falscher Schluessel wird erkannt statt Kauderwelsch zu liefern. Rollen-Guards (send/recv) gegen Fehlbenutzung. - CLI genkey erzeugt gerichtetes Keypaar (meine_seite/partner_seite). - Web-App auf v2 umgestellt; Senden liefert aktualisierten send.key zum Download (Browser-Sandbox kann nicht auf den Stick schreiben). - PWA: manifest + service worker (offline) + icons. - Interop CLI<->Web in beide Richtungen per Node-Test abgesichert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
42 lines
1.8 KiB
JavaScript
42 lines
1.8 KiB
JavaScript
// Interop-Test v2: lädt EXAKT den Core aus der ausgelieferten index.html und
|
|
// prüft Byte-Kompatibilität mit dem Python-CLI (richtungsgetrennte Schlüssel).
|
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
|
|
const U = (p) => new Uint8Array(readFileSync(new URL(p, import.meta.url)));
|
|
const html = readFileSync(new URL('./index.html', import.meta.url), 'utf8');
|
|
const core = html.match(/==CORE START==.*?\*\/([\s\S]*?)\/\*\s*==CORE END==/)[1];
|
|
new Function(core)();
|
|
const SP = globalThis.SP;
|
|
|
|
let fails = 0;
|
|
const ok = (c, m) => { console.log((c ? ' ✓ ' : ' ✗ ') + m); if (!c) fails++; };
|
|
|
|
// A: CLI (send.key) -> Web-Core (recv.key)
|
|
{
|
|
const rgb = U('./_a_rgb.bin');
|
|
const recv = SP.parseKey(U('../t2/rel_partner_seite/recv.key'));
|
|
const info = SP.extract(rgb);
|
|
const plain = SP.otpXor(info.ciphertext, recv.material, info.offset);
|
|
const text = new TextDecoder().decode(plain);
|
|
console.log('A) CLI → Web');
|
|
ok(SP.sameStream(info.streamId, recv.streamId), 'stream_id passt zum recv.key');
|
|
ok(text === 'MsgA vom CLI 🕵️', 'Klartext: ' + JSON.stringify(text));
|
|
}
|
|
|
|
// B: Web-Core (send.key) -> CLI (recv.key)
|
|
{
|
|
const rgb = U('./_b_rgb.bin');
|
|
const send = SP.parseKey(U('../t2/rel_partner_seite/send.key'));
|
|
const msg = 'MsgB aus dem Browser-Core 🌐';
|
|
ok(send.role === SP.ROLE_SEND, 'partner send.key hat Rolle SEND');
|
|
const plain = new TextEncoder().encode(msg);
|
|
const ct = SP.otpXor(plain, send.material, send.sendOffset);
|
|
const payload = SP.buildStego(send.streamId, send.sendOffset, ct);
|
|
SP.embed(rgb, payload);
|
|
writeFileSync(new URL('./_b_out_rgb.bin', import.meta.url), rgb);
|
|
console.log('B) Web → CLI');
|
|
ok(true, `eingebettet (${plain.length} B ab Offset ${send.sendOffset}) → _b_out_rgb.bin`);
|
|
}
|
|
|
|
process.exit(fails ? 1 : 0);
|