From 5c24e160bc6b535b712d93bfdc347418bb494bb6 Mon Sep 17 00:00:00 2001 From: Jonas Arnold Date: Thu, 2 Mar 2023 15:51:50 +0100 Subject: [PATCH] first version of XTEA CBC --- SW01-XTEA-Cipher/SW01-XTEA-Cipher.sln | 10 ++ .../SW02-XTEA-CBC/SW02-XTEA-CBC.vcxproj | 141 +++++++++++++++ .../SW02-XTEA-CBC.vcxproj.filters | 36 ++++ SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.c | 37 ++++ SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.h | 25 +++ SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.c | 39 +++++ SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.h | 26 +++ SW01-XTEA-Cipher/SW02-XTEA-CBC/main.c | 163 ++++++++++++++++++ .../SW02-XTEA-CBC/musterloesung_XTEA | Bin 0 -> 13912 bytes 9 files changed, 477 insertions(+) create mode 100644 SW01-XTEA-Cipher/SW02-XTEA-CBC/SW02-XTEA-CBC.vcxproj create mode 100644 SW01-XTEA-Cipher/SW02-XTEA-CBC/SW02-XTEA-CBC.vcxproj.filters create mode 100644 SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.c create mode 100644 SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.h create mode 100644 SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.c create mode 100644 SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.h create mode 100644 SW01-XTEA-Cipher/SW02-XTEA-CBC/main.c create mode 100644 SW01-XTEA-Cipher/SW02-XTEA-CBC/musterloesung_XTEA diff --git a/SW01-XTEA-Cipher/SW01-XTEA-Cipher.sln b/SW01-XTEA-Cipher/SW01-XTEA-Cipher.sln index 945b8a1..523d05d 100644 --- a/SW01-XTEA-Cipher/SW01-XTEA-Cipher.sln +++ b/SW01-XTEA-Cipher/SW01-XTEA-Cipher.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.4.33103.184 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SW01-XTEA-Cipher", "SW01-XTEA-Cipher\SW01-XTEA-Cipher.vcxproj", "{0A55D2C2-29E0-459E-9D86-975DAA49A8FC}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SW02-XTEA-CBC", "SW02-XTEA-CBC\SW02-XTEA-CBC.vcxproj", "{101384C8-6D89-428A-A336-D82A488483B2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -21,6 +23,14 @@ Global {0A55D2C2-29E0-459E-9D86-975DAA49A8FC}.Release|x64.Build.0 = Release|x64 {0A55D2C2-29E0-459E-9D86-975DAA49A8FC}.Release|x86.ActiveCfg = Release|Win32 {0A55D2C2-29E0-459E-9D86-975DAA49A8FC}.Release|x86.Build.0 = Release|Win32 + {101384C8-6D89-428A-A336-D82A488483B2}.Debug|x64.ActiveCfg = Debug|x64 + {101384C8-6D89-428A-A336-D82A488483B2}.Debug|x64.Build.0 = Debug|x64 + {101384C8-6D89-428A-A336-D82A488483B2}.Debug|x86.ActiveCfg = Debug|Win32 + {101384C8-6D89-428A-A336-D82A488483B2}.Debug|x86.Build.0 = Debug|Win32 + {101384C8-6D89-428A-A336-D82A488483B2}.Release|x64.ActiveCfg = Release|x64 + {101384C8-6D89-428A-A336-D82A488483B2}.Release|x64.Build.0 = Release|x64 + {101384C8-6D89-428A-A336-D82A488483B2}.Release|x86.ActiveCfg = Release|Win32 + {101384C8-6D89-428A-A336-D82A488483B2}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SW01-XTEA-Cipher/SW02-XTEA-CBC/SW02-XTEA-CBC.vcxproj b/SW01-XTEA-Cipher/SW02-XTEA-CBC/SW02-XTEA-CBC.vcxproj new file mode 100644 index 0000000..6848610 --- /dev/null +++ b/SW01-XTEA-Cipher/SW02-XTEA-CBC/SW02-XTEA-CBC.vcxproj @@ -0,0 +1,141 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {101384c8-6d89-428a-a336-d82a488483b2} + SW02XTEACBC + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SW01-XTEA-Cipher/SW02-XTEA-CBC/SW02-XTEA-CBC.vcxproj.filters b/SW01-XTEA-Cipher/SW02-XTEA-CBC/SW02-XTEA-CBC.vcxproj.filters new file mode 100644 index 0000000..01e9879 --- /dev/null +++ b/SW01-XTEA-Cipher/SW02-XTEA-CBC/SW02-XTEA-CBC.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.c b/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.c new file mode 100644 index 0000000..4dba116 --- /dev/null +++ b/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.c @@ -0,0 +1,37 @@ +/** + *--------------------------------------------------------------------\n + * HSLU T&A Hochschule Luzern Technik+Architektur \n + *--------------------------------------------------------------------\n + * + * \brief model solution for ASYD assignment crypto 01 + * \file + * \author SIMON FREI, stefano.nicora@hslu.ch + * \date 04.10.22 + * + *-------------------------------------------------------------------- + */ + +#include +#include "XTEA-CBC.h" +#include "XTEA.h" + +#define INITIALIZATION_VECTOR { 'COFE', 'SIMI' } + +void encipher_CBC(unsigned int num_cycles, uint32_t v[2], uint32_t const k[4]) { + static uint32_t v_prev[2] = INITIALIZATION_VECTOR; + v[0] = v[0] ^ v_prev[0]; + v[1] = v[1] ^ v_prev[1]; + encipher(num_cycles, v, k); + v_prev[0] = v[0]; + v_prev[1] = v[1]; +} + +void decipher_CBC(unsigned int num_cycles, uint32_t v[2], uint32_t const k[4]) { + static uint32_t v_prev[2] = INITIALIZATION_VECTOR; + uint32_t v_input[2] = { v[0], v[1] }; + decipher(num_cycles, v, k); + v[0] = v[0] ^ v_prev[0]; + v[1] = v[1] ^ v_prev[1]; + v_prev[0] = v_input[0]; + v_prev[1] = v_input[1]; +} diff --git a/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.h b/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.h new file mode 100644 index 0000000..8ce9a35 --- /dev/null +++ b/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA-CBC.h @@ -0,0 +1,25 @@ +/** + *--------------------------------------------------------------------\n + * HSLU T&A Hochschule Luzern Technik+Architektur \n + *--------------------------------------------------------------------\n + * + * \brief model solution for ASYD assignment crypto 01 + * \file + * \author Stefano Nicora, stefano.nicora@hslu.ch + * \date 04.10.22 + * + *-------------------------------------------------------------------- + */ + +#ifndef XTEA_CBC_H_ +#define XTEA_CBC_H_ +#define _CRT_SECURE_NO_WARININGS +#pragma warning(disable:4996) + +#include + +void encipher_CBC(unsigned int num_cycles, uint32_t v[2], uint32_t const k[4]); + +void decipher_CBC(unsigned int num_cycles, uint32_t v[2], uint32_t const k[4]); + +#endif // !XTEA_CBC_H_ \ No newline at end of file diff --git a/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.c b/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.c new file mode 100644 index 0000000..fd2a74c --- /dev/null +++ b/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.c @@ -0,0 +1,39 @@ +/** + *--------------------------------------------------------------------\n + * HSLU T&A Hochschule Luzern Technik+Architektur \n + *--------------------------------------------------------------------\n + * + * \brief model solution for ASYD assignment crypto 01 + * \file + * \author Stefano Nicora, stefano.nicora@hslu.ch + * \date 04.10.22 + * + *-------------------------------------------------------------------- + */ + +#include +#include "XTEA.h" + +void encipher(unsigned int num_cycles, uint32_t v[2], uint32_t const k[4]) { + unsigned int i; + const uint32_t delta = 0x9E3779B9; + uint32_t v0 = v[0], v1 = v[1], sum = 0; + for (i = 0; i < num_cycles; i++) { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); + } + v[0] = v0; v[1] = v1; +} + +void decipher(unsigned int num_cycles, uint32_t v[2], uint32_t const k[4]) { + unsigned int i; + const uint32_t delta = 0x9E3779B9; + uint32_t v0 = v[0], v1 = v[1], sum = delta * num_cycles; + for (i = 0; i < num_cycles; i++) { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + } + v[0] = v0; v[1] = v1; +} diff --git a/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.h b/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.h new file mode 100644 index 0000000..048d7dd --- /dev/null +++ b/SW01-XTEA-Cipher/SW02-XTEA-CBC/XTEA.h @@ -0,0 +1,26 @@ +/** + *--------------------------------------------------------------------\n + * HSLU T&A Hochschule Luzern Technik+Architektur \n + *--------------------------------------------------------------------\n + * + * \brief model solution for ASYD assignment crypto 01 + * \file + * \author Stefano Nicora, stefano.nicora@hslu.ch + * \date 04.10.22 + * + *-------------------------------------------------------------------- + */ + +#ifndef XTEA_H_ +#define XTEA_H_ +#define _CRT_SECURE_NO_WARININGS +#pragma warning(disable:4996) + +#include + +void encipher(unsigned int num_cycles, uint32_t v[2], uint32_t const k[4]); + +void decipher(unsigned int num_cycles, uint32_t v[2], uint32_t const k[4]); + +#endif // !XTEA_H_ + diff --git a/SW01-XTEA-Cipher/SW02-XTEA-CBC/main.c b/SW01-XTEA-Cipher/SW02-XTEA-CBC/main.c new file mode 100644 index 0000000..fd46996 --- /dev/null +++ b/SW01-XTEA-Cipher/SW02-XTEA-CBC/main.c @@ -0,0 +1,163 @@ +/** + *--------------------------------------------------------------------\n + * HSLU T&A Hochschule Luzern Technik+Architektur \n + *--------------------------------------------------------------------\n + * + * \brief model solution for ASYD assignment crypto 01 + * \file + * \author Stefano Nicora, stefano.nicora@hslu.ch + * \date 12.10.22 + * + *-------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include "XTEA-CBC.h" + +void encrypt(uint32_t key[4], uint8_t numberOfCycles); +void decrypt(uint32_t key[4], uint8_t numberOfCycles); + +/* source: https://en.wikipedia.org/wiki/XTEA */ + +/* filenames as of this code: + * plaintext.txt => holds the message you want to encrypt + * encrypted.cip => holds the encrypted message + * decrypted.txt => holds the decrypted output from "encrypted.cip" + */ + +void main(void) { + uint32_t key[4] = { 1, 3, 1, 2}; + encrypt(key, 32); + decrypt(key, 32); +} + +void encrypt(uint32_t key[4], uint8_t numberOfCycles) { + + /* duplicate code that hasn't been moved to a separate function for readability reasons */ + /* -------------------------------------------------------------------- */ + + /* variables */ + uint32_t amountOfCharsInFile = 0; + /* https://www.programiz.com/c-programming/c-file-input-output */ + FILE* fileHandle = fopen("plaintext.txt", "r"); + if (fileHandle == NULL) { + return; + } + + /* get total number of characters in file to encrypt */ + while (getc(fileHandle) != EOF) { + amountOfCharsInFile++; + } + + /* allocate enough memory for the whole file to be read */ + char* inputText = (char*)calloc(amountOfCharsInFile + 8, sizeof(char)); /* add 8 for extra padding in case the file contains some sort of rest in regards to amountOfCharsInFile % 8 */ + if (inputText == NULL) { + return; + } + + /* close and reopen file to start at the beginning of the file again */ + fclose(fileHandle); + fileHandle = fopen("plaintext.txt", "r"); + if (fileHandle == NULL) { + return; + } + + /* read the whole file into memory */ + for (uint32_t i = 0; i < amountOfCharsInFile; i++) { + inputText[i] = getc(fileHandle); + } + fclose(fileHandle); + /* -------------------------------------------------------------------- */ + + /* loop through the whole array to encrypt the whole message + This happens two blocks of 32bit (= 8 characters) at a time + Hence the increase of "i" by 8 + */ + for (uint32_t i = 0; i < amountOfCharsInFile; i += 8) { /* + 8 to compensate for the requested element size of the encipher function (32 bit) */ + /* dereferencing and forwarding the address of the key ensures, + * that we don't ready from a random address in memory. Rookie mistakes happen :) */ + encipher_CBC(numberOfCycles, &(inputText[i]), &(*key)); + } + + /* generate new file where encryption is stored */ + fileHandle = fopen("encrypted.cip", "w"); + if (fileHandle == NULL) { + return; + } + /* fill new file with content */ + /* to get the extra character padding we might unintentionally drop + * we need to read up to a multiple of 8 (32 bit) + */ + for (uint32_t i = 0; i < (amountOfCharsInFile + (8-(amountOfCharsInFile%8))); i++) { + putc(inputText[i], fileHandle); + } + fclose(fileHandle); + free(inputText); +} + +void decrypt(uint32_t key[4], uint8_t numberOfCycles) { + + /* duplicate code that hasn't been moved to a separate function for readability reasons */ + /* -------------------------------------------------------------------- */ + + /* variables */ + uint32_t amountOfCharsInFile = 0; + + /* https://www.programiz.com/c-programming/c-file-input-output */ + FILE* fileHandle = fopen("encrypted.cip", "r"); + if (fileHandle == NULL) { + return; + } + + /* get total number of characters in file to decrypt */ + while (getc(fileHandle) != EOF) { + amountOfCharsInFile++; + } + + /* allocate memory for the whole file to be read */ + char* inputText = (char*)calloc(amountOfCharsInFile + 10, sizeof(char)); /* add 10 for extra padding */ + if (inputText == NULL) { + return; + } + + /* close and reopen file to start at the beginning of the file again */ + fclose(fileHandle); + fileHandle = fopen("encrypted.cip", "r"); + if (fileHandle == NULL) { + return; + } + + /* read the whole file into memory */ + for (uint32_t i = 0; i < amountOfCharsInFile; i++) { + inputText[i] = getc(fileHandle); + } + fclose(fileHandle); + + /* -------------------------------------------------------------------- */ + + /* loop through the whole array to encrypt the whole message + This happens two blocks of 32bit (= 4 characters) at a time + Hence the increase of "i" by 8 + */ + + for (uint32_t i = 0; i < amountOfCharsInFile; i += 8) { /* i += 8*/ + /* dereferencing and forwarding the address of the key ensures, + * that we don't ready from a random address in memory. Rookie mistakes happen :) */ + decipher_CBC(numberOfCycles, &(inputText[i]), &(*key)); + } + + /* generate new file where the decryption is stored */ + fileHandle = fopen("decrypted.txt", "w"); + if (fileHandle == NULL) { + return; + } + /* fill new file with content */ + for (uint32_t i = 0; i < amountOfCharsInFile; i++) { + putc(inputText[i], fileHandle); + } + fclose(fileHandle); + free(inputText); +} \ No newline at end of file diff --git a/SW01-XTEA-Cipher/SW02-XTEA-CBC/musterloesung_XTEA b/SW01-XTEA-Cipher/SW02-XTEA-CBC/musterloesung_XTEA new file mode 100644 index 0000000000000000000000000000000000000000..233f4bb16c7dd0a776d6da2af5bce91e78fbeb97 GIT binary patch literal 13912 zcmeHOYiwM_6+XMykRMc0OWYVj5uvE1RgzY1q^2dQs@6P&B8aNAyi%2*wJ9hns0~ekEXCP=XJ*d& z?%g$sAb%=(lDlW-n{&>bnK?7}&chF^Y+mK}`AC9A&l0BwCu$^UGUn8n2uP5Y(q#P3 zqbq0v(q#(M`9V#PtHW8NTIeK$Tc9kr)UN?Aooo1niiJ!sF?prPTQf8&lvHi>FWY)( zp3XlsPiqvq*Vu8uP?6&#%N;RtM~s}%j4@28)Q{`NPpi@Ar7MufK`8Tbxc%L9gyVLl zN*2+GhDoT%-2pka^Fo7BPa8~mW3|g_W4}=8hniSdTTLvoDApD4?OPNICBvPIZw#ao zfjV99*)W9rxM|&;w0LsogVUG%e8K8@)7zg|_M=b#`M2g@u-$9}>th}c%x~OI;hZPs zasGt{i^}O_iN>&~if*?HHEx7byM*Ge0$Wf5p9*Yd3H-`2a5ke9|BYkdRb$|6btyet zfZKSyfrmjU{#9e(JAm7Gib6*;9j5j~Pc%+Fy@-a|63H}$L$O!_csQ0wMagl(eIcj4 zD;|n<-OoulN7zZFL&>z$9qNixdomg&2H8UvQ&aPrhDPW5K;05@*0kQ{M54)PM^`Ex zO}5_F7)!*Xt)aFU>*?rD#El+DvzBDc8|^3eKT;{3=_4PlMO6HLcmHGP8b4{z<9UHw z7(QqQ)G;%V2R-;!gCD3aRq_ZiHt9F;gcCKq1J^@ z5fF5#3wPHm=)!qSN?7f}rwIr;viVQ@Ml9-YAQ~9i{M_C_%Xx#dPXXUabYRB0rflW# z@_yT2{YJHIy)F;(j?M4~vz2~Qc`7{t=>@Lz6r>wm=?bLVTg#_HbUx^EqW1^!8bkWP{I{C2 zA@HBFeESLQ#4=v~`9!ZQ`0RmK>!&`rWBzCLyPgC8Hpn)dYRa}LS$|%Z%NyDJN7XN< z%PG4HWp3P7zbxpZo1pgqWty^}2UQu@1+#l#_i;QnZQZbOn{V0a@?dsk^Yf}NrN2;oGHh70_4ju+A=Q4(X zXKG9uWn_@2bc5z~Bc9j2rMx9$(Y5C-1NNvgV0&gc+e9-muzv{gOm*-u`t9Bqvbk2S zFWciI@NwNMseg#;hcvet+Nz)X@r$(C5bDKc*;{CC#@&7ww~lMMe_ZXjmdmfh$V{i~kVDJZ zFNtWUZ|m}Yru6jk{`b!1c0+$QQx(is6MaZisTK41Y_~6P-bwIPmr-4P4!*$kwBaZ4 zulblWPOy$y&@oHvu%}Qf%e(^ITi(mw@+MPj4*rd~cQ(uX8TrG|%loxQzQ&bPP|2|6*>-Sk|>uF!t4$ScV8{2EUyX0*XCLGC>X|o_+l>9s zZSywfMLnMc#rthG_aEMiigG`2+HdH{<`>l*b)J4zHurdJ9xN~2uSxI~^y|XWe(g}U zjrMB>eZ}p3CvaE4s`6UBs^;kXK;@dZXch-P^N&iRp`1d`E_-}_7_Ye3l zedS|}i%-JVzEAMpJZt&)51eb<_0~vkciKk>XJH(&o}b>IIy-F5*`Jz#`Pr(1zh8Fk zMq2*HkNvaWpO3M7x}|>KNB1=B`y|}BPyC7HcO8~1mO58t*NlIoYJCx-9vbhIxW zNcW|I-DmJpa|Aeld!70ums9JFv$@<(q&I>-19|}T z2*ewRLL4$Y>0$UAA^%eG>vZt(uUH)}%pLkV$_VRj^>yZHu z#%De-&UHEp{6@B=z9Q&fTS1Hu;5msp;d?~m>ngD0LG(*Jm7nHv&7e}&9dDmd<#7H{ zJhveKxRKj4>8XkSv}WM^5Ad8pn;diJCv`s8b1Lw?Xe+jh?P2+bT@wZ_X?(QoF>B>+ z|Kq-vw@=Eim2! z|Nku@=M!=s!Al7aYc;`kkPdPVCVSy8n)8USn0z_+kaJe7eO0*JP&xnLbqfc{|L9yU z!Rg2KGBbZBYnug#oDm!{`Ld_~GZsRSy?kEZakx~I{I8sOoHXYbMh%@Z9K1f`AZHGI zZpPuPIkXUbl1Yo*A}?nTQa+Yrsyl$>d|ntMaAZ%9xAz zBj?R>&NP;4Id78lrLp+(xHQzoqDHZtV>LB4e#2h4BHGp!iraOy0UY`*TKshrv#+nc zzOJ^eju*Y36D;!O?+LisEbMW}xq2aPQJ*-BE5pJjr1+}~CJWvxep-l6Ao1ryd?HD| z7vhsh{G|||OyY-y_>{cA7UE-_Ut?5DKe+@fnwGz>;et`G3X<_&h)<{E)7^-UTi8jk zc{9NiESfdirrE`2FZd!DW8a z{KfvD@#6m7^SR}g(;3eMC3=o}{9)*G^-QBmnNY#Uf%ml7elPwng9knQy4|Ws<_Xrp zfv+O59(k{6l&A{0&(*)&e;l-)Vt>0z@fYK_8vXMA)LKMOu|MCX^c3T|+!^$wXIyB! z*bjT5=kxsGwUX^KgD~_8!j|*s@y`3&p6P_Mq=F#!*Lw6nbRPZkei3D&XQxNc5Ex3; zSNM;6_#Z*JK2+9=b2+8->;XUDaPiJFzfyWW%z5XTXAQr6@31t7mla+-@0~Duyz|mh ze30de>6t$rg;y2Lt0P=5fARd&K8Bv;80Bss1AkQE(`dkaD5|}5 z)ML*W{J%H+GLF<>g}S3o zq_?|!6GU7o2b}2w*1KC**25mYk_QrvwJ&0pK%xbLt2Wf%w$fR-ZiR!Jc7>u5a#nn6 zUHxrq8VhsO1wTNzzv--8Z8WT2v4NbX=JgHr&CdE&t6EmJI<55$%_~`}x)vBt^{Pt9 zQR8{80Jf!4qc;Ex?imJM*9iG)qC4$GBcXH%MY4D_9zmt_T}3yOy4C0g%weclI(mW8 z!_?K&8BLlyknSw>DN5Dm5?`Dw%q+ak=tNQpr!y3f;HIOxR9V2hWKfovYYMR6BQK%)H4yDIp57UOtfaJrc6lu!aVQRTcZE@E0=n=M zPz7jZ@DU1NS+i17K_y z+s8rn0fox?Qs?TjB+m4Ec-->&eFw8{9b_g~@GOJW-3hn+pvW0oCI%ZFUil}0yX9pc zL#UVExJTZir;WVypX_%C)$5Qvd%pby+3S(FO@Trq!f2?s{NH)xW&cEID_71HJk3Fa z$m6>mJT^GUx<&p@!^^f)l~9g&yyl>8k`#@H|Z zC34a)Ly%<_k(YJUUR+k>5LCaTKO!&mJ!HA%WgqCIk?$N8RWXqh`frcC{N2axwiXmS zb!xQ!lKu!0)+P4K_wGhpb4WQlrEQfs(@*iR{k5EM1(CnTg>jU5Ik>6#uFlcF58Ila vnye|mM|kZi_Q?Ff*hcR8~bmb66e$Pm=xzOUd@v literal 0 HcmV?d00001