ztw.psm1

# ═══════════════════════════════════════════════════════════════
# ZTW — Zero Trust World 2026
# Jakoby's live demo module
# Install-Module ztw → Import-Module ztw
# ═══════════════════════════════════════════════════════════════

# ── On Import: drop cat.png and calc.ps1 to Desktop ─────────────
$ModuleRoot = $PSScriptRoot
$Desktop    = [Environment]::GetFolderPath('Desktop')

foreach ($file in @('cat.png', 'calc.ps1')) {
    $src = Join-Path $ModuleRoot $file
    $dst = Join-Path $Desktop $file
    if (Test-Path $src) {
        Copy-Item -Path $src -Destination $dst -Force
    }
}

Write-Host ""
Write-Host " [ZTW] Module loaded. cat.png and calc.ps1 dropped to Desktop." -ForegroundColor Cyan
Write-Host ""

# ═══════════════════════════════════════════════════════════════
# AES HELPERS (used by Encode/Decode-inEmoji)
# ═══════════════════════════════════════════════════════════════

function Encrypt-AES {
    param(
        [Parameter(Mandatory=$true)]  [string] $PlainText,
        [Parameter(Mandatory=$true)]  [string] $Key
    )
    $aes  = [System.Security.Cryptography.Aes]::Create()
    $aes.Key = [System.Text.Encoding]::UTF8.GetBytes($Key.PadRight(16).Substring(0,16))
    $aes.IV  = New-Object byte[] 16
    $enc = $aes.CreateEncryptor()
    $bytes = [System.Text.Encoding]::UTF8.GetBytes($PlainText)
    $result = $enc.TransformFinalBlock($bytes, 0, $bytes.Length)
    $aes.Dispose()
    return [Convert]::ToBase64String($result)
}

function Decrypt-AES {
    param(
        [Parameter(Mandatory=$true)]  [string] $CipherText,
        [Parameter(Mandatory=$true)]  [string] $Key
    )
    $aes  = [System.Security.Cryptography.Aes]::Create()
    $aes.Key = [System.Text.Encoding]::UTF8.GetBytes($Key.PadRight(16).Substring(0,16))
    $aes.IV  = New-Object byte[] 16
    $dec = $aes.CreateDecryptor()
    $bytes = [Convert]::FromBase64String($CipherText)
    $result = $dec.TransformFinalBlock($bytes, 0, $bytes.Length)
    $aes.Dispose()
    return [System.Text.Encoding]::UTF8.GetString($result)
}

# ═══════════════════════════════════════════════════════════════
# PIXEL ENCODING
# ═══════════════════════════════════════════════════════════════

function Invoke-PixelScript {
    <#
    .SYNOPSIS
        Store a PowerShell script in the pixels of an image.

    .EXAMPLE
        Invoke-PixelScript -Script "$env:USERPROFILE\Desktop\calc.ps1" `
                           -Image "$env:USERPROFILE\Desktop\cat.png" `
                           -Out "$env:USERPROFILE\Downloads\out.png"
    #>

    [CmdletBinding()]
    Param (
        [Parameter(Position = 0, Mandatory = $true)]
        [String] $Script,

        [Parameter(Position = 1, Mandatory = $true)]
        [String] $Out,

        [Parameter(Position = 2, Mandatory = $false)]
        [String] $Image,

        [Parameter(Position = 3, Mandatory = $false)]
        [String] $ExecPath = $Out
    )

    $ErrorActionPreference = "Stop"
    Add-Type -AssemblyName System.Drawing

    $Script = Resolve-Path $Script
    if ($Image) { $Image = Resolve-Path $Image }

    $ScriptContent = [IO.File]::ReadAllText($Script)
    $payload = [System.Text.Encoding]::ASCII.GetBytes($ScriptContent)

    if ($Image) {
        $img = New-Object System.Drawing.Bitmap $Image
    } else {
        $sideLength = [Math]::Ceiling([Math]::Sqrt($payload.Length / 3)) * 3
        $img = New-Object System.Drawing.Bitmap $sideLength, $sideLength
    }

    $width  = $img.Width
    $height = $img.Height

    for ($y = 0; $y -lt $height; $y++) {
        for ($x = 0; $x -lt $width; $x++) {
            $index = $y * $width + $x
            if ($index -lt $payload.Length) {
                $byteValue = $payload[$index]
                $color  = $img.GetPixel($x, $y)
                $newR   = ($color.R -band 0xF0) -bor ($byteValue -shr 4)
                $newG   = ($color.G -band 0xF0) -bor ($byteValue -band 0x0F)
                $newColor = [System.Drawing.Color]::FromArgb($newR, $newG, $color.B)
                $img.SetPixel($x, $y, $newColor)
            }
        }
    }

    $img.Save($Out, [System.Drawing.Imaging.ImageFormat]::Png)
    $img.Dispose()

    $pscmd = @"
sal a New-Object;Add-Type -A System.Drawing;
`$g=a System.Drawing.Bitmap("$ExecPath");
`$o=a Byte[] $($width*$height);
(0..$($height-1))|%{
    foreach(`$x in 0..$($width-1)) {
        `$p=`$g.GetPixel(`$x,`$_);
        `$o[`$_*$width+`$x]=[math]::Floor((`$p.R -band 0x0F)*16)+(`$p.G -band 0x0F);
    }
};
`$g.Dispose();
IEX([System.Text.Encoding]::ASCII.GetString(`$o[0..$($payload.Length-1)]))
"@

    return $pscmd
}

# ═══════════════════════════════════════════════════════════════
# EMOJI ENCODING
# ═══════════════════════════════════════════════════════════════

function Encode-inEmoji {
    <#
    .SYNOPSIS
        Encode a string inside an emoji using Unicode variation selectors.

    .EXAMPLE
        Encode-inEmoji -string 'secret message'
        Encode-inEmoji -string 'secret message' -key 'secretKey1234567' -emoji 😊
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]  $string,
        [Parameter(Mandatory=$false)] $emoji = '😈',
        [Parameter(Mandatory=$false)] $key
    )

    if ($key) { $string = Encrypt-AES -PlainText $string -Key $key }

    $selectors = @([char]0xFE00..[char]0xFE0F)
    $bytes  = [System.Text.Encoding]::UTF8.GetBytes($string)
    $binary = ($bytes | ForEach-Object { [Convert]::ToString($_, 2).PadLeft(8, '0') }) -join ''
    $encoded = $emoji

    for ($i = 0; $i -lt $binary.Length; $i += 4) {
        $nibble   = [Convert]::ToInt32($binary.Substring($i, 4), 2)
        $encoded += $selectors[$nibble]
    }

    Set-Clipboard -Value $encoded
    Write-Host " [ZTW] Encoded and copied to clipboard." -ForegroundColor Cyan
}

function Decode-inEmoji {
    <#
    .SYNOPSIS
        Retrieve data hidden inside an emoji from the clipboard.

    .EXAMPLE
        Decode-inEmoji
        Decode-inEmoji -key 'secretKey1234567'
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false)]
        [string] $key
    )

    $utf8NoBom = New-Object System.Text.UTF8Encoding($false)
    $encoded   = Get-Clipboard

    if (-not $encoded) { Write-Error "Clipboard is empty."; return }

    $firstChar   = $encoded[0]
    $emojiLength = if ([char]::IsHighSurrogate($firstChar)) { 2 } else { 1 }

    if ($encoded.Length -le $emojiLength) { Write-Error "No selectors found."; return }

    $selectorsInput = $encoded.Substring($emojiLength)
    $binary = ''

    for ($i = 0; $i -lt $selectorsInput.Length; $i++) {
        $selectorValue = [int][char]$selectorsInput[$i] - 0xFE00
        if ($selectorValue -lt 0 -or $selectorValue -gt 15) {
            Write-Error "Invalid selector: $($selectorsInput[$i])"; return
        }
        $binary += [Convert]::ToString($selectorValue, 2).PadLeft(4, '0')
    }

    if ($binary.Length % 8 -ne 0) { Write-Error "Incomplete binary data."; return }

    $bytes = for ($i = 0; $i -lt $binary.Length; $i += 8) {
        [Convert]::ToInt32($binary.Substring($i, 8), 2)
    }

    $keyDecoded = $utf8NoBom.GetString($bytes)
    $keyCleaned = ($keyDecoded.ToCharArray() | Where-Object { [int]$_ -lt 128 }) -join ''

    if ($key) { $keyCleaned = Decrypt-AES -CipherText $keyCleaned -Key $key }

    Write-Output $keyCleaned
}

# ═══════════════════════════════════════════════════════════════
# EXPORTS
# ═══════════════════════════════════════════════════════════════
Export-ModuleMember -Function @(
    'Invoke-PixelScript',
    'Encode-inEmoji',
    'Decode-inEmoji',
    'Encrypt-AES',
    'Decrypt-AES'
)