function getRandomCiphertext($key, $iv)
{
    $texts = ['MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=', 'MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=', 'MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==', 'MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==', 'MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl', 'MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==', 'MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==', 'MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=', 'MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=', 'MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93'];
    $texts = array_map('base64_decode', $texts);
    $text = $texts[rand(0, 9)];
    // our implementation automatically PKCS7 pads
    return encryptAES128CBC($text, $key, $iv);
}
function randomlyEncryptECBorCBC($data)
{
    $key = getRandomBytes(16);
    $pad1 = getRandomBytes(rand(5, 10));
    $pad2 = getRandomBytes(rand(5, 10));
    if (rand(0, 1)) {
        return encryptAES128CBC("{$pad1}{$data}{$pad2}", $key, getRandomBytes(16));
    }
    return encryptAES128ECB("{$pad1}{$data}{$pad2}", $key);
}
function getQuery($userData, $key, $iv)
{
    $data = http_build_query(['comment1' => 'cooking MCs', 'userdata' => $userData, 'comment2' => ' lke a pound of bacon'], null, ';', PHP_QUERY_RFC3986);
    return encryptAES128CBC($data, $key, $iv);
}
function decryptAES128CBC($data, $key, $iv = "", $strictPadding = false)
{
    $blocks = str_split($data, 16);
    foreach ($blocks as &$block) {
        $nextIV = $block;
        $block = $iv ^ _decryptAES128ECB($block, $key);
        $iv = $nextIV;
    }
    $plaintext = implode($blocks);
    try {
        return removePKCS7Padding($plaintext);
    } catch (Exception $e) {
        if ($strictPadding) {
            throw $e;
        }
        return $plaintext;
    }
}
// don't output if we're included into another script.
if (!debug_backtrace()) {
    $encrypted = base64_decode(file_get_contents('10-data.txt'));
    $key = 'YELLOW SUBMARINE';
    $decrypted = decryptAES128CBC($encrypted, $key);
    $homebrewEncrypted = encryptAES128CBC($decrypted, $key);
    $homebrewDecrypted = decryptAES128CBC($homebrewEncrypted, $key);
    print "Sanity check:\n";
    $sanity = $decrypted === $homebrewDecrypted;
    print $sanity ? "Success!\n\n" : "Failure :(\n\n";
    print "Decrypted data:\n";
    print "{$decrypted}\n";
}
 function send($data)
 {
     $key = sha1($this->shared, true);
     $iv = getRandomBytes(16);
     $message = $iv . encryptAES128CBC($data, $key, $iv);
     print "{$this->name}: sending: {$data}\n";
     $func = $this->onSend;
     $func($message);
 }
 function send($data)
 {
     $obj = new \stdClass();
     $obj->msg = 'dat';
     $obj->data = $data;
     $data = json_encode($obj);
     if (!is_null($this->shared)) {
         $key = sha1($this->shared, true);
         $iv = getRandomBytes(16);
         $data = $iv . encryptAES128CBC($data, $key, $iv);
     }
     $dataLen = strlen($data);
     print "{$this->name}: sending {$dataLen} bytes\n";
     $func = $this->onSend;
     $func($data);
 }