From 7ed3d4db89c09919bb387cd38f0a407bd595099a Mon Sep 17 00:00:00 2001 From: codex Date: Sun, 31 May 2026 04:47:36 +0000 Subject: [PATCH] feat: implement Steganography CI/CD protocol (The Trojan Payload) --- .forgejo/workflows/cd.yaml | 20 +++++ docs/assets/carriers/institute_logo.png | 3 + .../recursive_coherence_infographic.png | 3 + scripts/stego_decoder.py | 83 +++++++++++++++++++ scripts/stego_encoder.py | 65 +++++++++++++++ 5 files changed, 174 insertions(+) create mode 100644 docs/assets/carriers/institute_logo.png create mode 100644 docs/assets/carriers/recursive_coherence_infographic.png create mode 100644 scripts/stego_decoder.py create mode 100644 scripts/stego_encoder.py diff --git a/.forgejo/workflows/cd.yaml b/.forgejo/workflows/cd.yaml index a31b2861..0d804b19 100644 --- a/.forgejo/workflows/cd.yaml +++ b/.forgejo/workflows/cd.yaml @@ -92,6 +92,26 @@ jobs: with: python-version: '3.x' + - name: Steganographic Encoding (The Trojan Payload) + run: | + echo "Compressing the Sovereign Canon vault..." + tar --exclude='./docs/assets/carriers' --exclude='./.git' -czf CANONICAL_VAULT.tar.gz . + + echo "Installing Python image processing libraries..." + pip install Pillow + + echo "Encoding vault into primary carrier (Institute Logo)..." + python3 scripts/stego_encoder.py CANONICAL_VAULT.tar.gz docs/assets/carriers/institute_logo.png docs/assets/encoded_logo.png + + echo "Encoding vault into secondary carrier (Infographic)..." + python3 scripts/stego_encoder.py CANONICAL_VAULT.tar.gz docs/assets/carriers/recursive_coherence_infographic.png docs/assets/encoded_infographic.png + + echo "Moving encoded assets to MkDocs build directory..." + mv docs/assets/encoded_logo.png docs/assets/institute_logo.png + mv docs/assets/encoded_infographic.png docs/assets/recursive_coherence_infographic.png + + echo "Steganographic injection complete." + - name: Build and Deploy Pages run: | if [ -f "mkdocs.yml" ]; then diff --git a/docs/assets/carriers/institute_logo.png b/docs/assets/carriers/institute_logo.png new file mode 100644 index 00000000..3a05528a --- /dev/null +++ b/docs/assets/carriers/institute_logo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:376def610f5bcf2f99c60f093ca8aa11518a5e1e87b3b8e24a6c0278651ca405 +size 8593456 diff --git a/docs/assets/carriers/recursive_coherence_infographic.png b/docs/assets/carriers/recursive_coherence_infographic.png new file mode 100644 index 00000000..fbc8cda7 --- /dev/null +++ b/docs/assets/carriers/recursive_coherence_infographic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:458011e25c64910b7685de5fbe109c8b49a2d21a51190669e34c75f457390a54 +size 11838035 diff --git a/scripts/stego_decoder.py b/scripts/stego_decoder.py new file mode 100644 index 00000000..f629bfc9 --- /dev/null +++ b/scripts/stego_decoder.py @@ -0,0 +1,83 @@ +import sys +from PIL import Image + +def decode_lsb(image_path, output_path): + print(f"[*] Extracting payload from {image_path}...") + + img = Image.open(image_path) + img = img.convert('RGB') + pixels = img.load() + width, height = img.size + + # 1. Read the first 64 bits (8 bytes) to get the payload length + header_bits = "" + bit_idx = 0 + header_length = 64 + + for y in range(height): + for x in range(width): + r, g, b = pixels[x, y] + + if bit_idx < header_length: + header_bits += str(r & 1) + bit_idx += 1 + if bit_idx < header_length: + header_bits += str(g & 1) + bit_idx += 1 + if bit_idx < header_length: + header_bits += str(b & 1) + bit_idx += 1 + + if bit_idx >= header_length: + break + if bit_idx >= header_length: + break + + payload_length_bytes = int(header_bits, 2) + payload_length_bits = payload_length_bytes * 8 + print(f"[*] Detected embedded payload of size: {payload_length_bytes} bytes.") + + # 2. Read the actual payload + payload_bits = "" + bit_idx = 0 + total_bits_to_read = header_length + payload_length_bits + + for y in range(height): + for x in range(width): + r, g, b = pixels[x, y] + + if bit_idx >= header_length and bit_idx < total_bits_to_read: + payload_bits += str(r & 1) + bit_idx += 1 + + if bit_idx >= header_length and bit_idx < total_bits_to_read: + payload_bits += str(g & 1) + bit_idx += 1 + + if bit_idx >= header_length and bit_idx < total_bits_to_read: + payload_bits += str(b & 1) + bit_idx += 1 + + if bit_idx >= total_bits_to_read: + break + if bit_idx >= total_bits_to_read: + break + + # Convert bits to bytes + payload_bytes = bytearray() + for i in range(0, len(payload_bits), 8): + byte = payload_bits[i:i+8] + payload_bytes.append(int(byte, 2)) + + # 3. Save Payload + with open(output_path, 'wb') as f: + f.write(payload_bytes) + + print(f"[+] Successfully extracted payload to {output_path}") + +if __name__ == "__main__": + if len(sys.argv) != 3: + print("Usage: python3 stego_decoder.py ") + sys.exit(1) + + decode_lsb(sys.argv[1], sys.argv[2]) diff --git a/scripts/stego_encoder.py b/scripts/stego_encoder.py new file mode 100644 index 00000000..2bfa157d --- /dev/null +++ b/scripts/stego_encoder.py @@ -0,0 +1,65 @@ +import sys +import os +from PIL import Image + +def encode_lsb(image_path, payload_path, output_path): + print(f"[*] Encoding {payload_path} into {image_path}...") + + # 1. Read Payload + with open(payload_path, 'rb') as f: + payload_bytes = f.read() + + # Inject header to denote length of the file (8 bytes / 64 bits) + payload_length = len(payload_bytes) + header = payload_length.to_bytes(8, byteorder='big') + full_payload = header + payload_bytes + + # Convert to binary string + binary_payload = ''.join([format(b, '08b') for b in full_payload]) + payload_len_bits = len(binary_payload) + print(f"[*] Payload is {payload_length} bytes ({payload_len_bits} bits).") + + # 2. Open Image + img = Image.open(image_path) + img = img.convert('RGB') + pixels = img.load() + width, height = img.size + + max_bits = width * height * 3 + if payload_len_bits > max_bits: + raise ValueError(f"Payload too large! Need {payload_len_bits} bits, but image can only hold {max_bits} bits.") + + # 3. Inject Data via LSB + bit_idx = 0 + for y in range(height): + for x in range(width): + if bit_idx >= payload_len_bits: + break + + r, g, b = pixels[x, y] + + if bit_idx < payload_len_bits: + r = (r & ~1) | int(binary_payload[bit_idx]) + bit_idx += 1 + if bit_idx < payload_len_bits: + g = (g & ~1) | int(binary_payload[bit_idx]) + bit_idx += 1 + if bit_idx < payload_len_bits: + b = (b & ~1) | int(binary_payload[bit_idx]) + bit_idx += 1 + + pixels[x, y] = (r, g, b) + + if bit_idx >= payload_len_bits: + break + + # 4. Save + img.save(output_path, format="PNG") + print(f"[+] Successfully saved encoded carrier to {output_path}") + +if __name__ == "__main__": + if len(sys.argv) != 4: + print("Usage: python3 stego_encoder.py ") + sys.exit(1) + + encode_lsb(sys.argv[2], sys.argv[1], sys.argv[3])