//=========================================================================== // 2005 - Crypto - Images // A combination of cryptography and steganography. // ASCII text is encoded into the low-order bit of the red pixels. // Bitmap (.bmp) images are used because of their simplicity. // Nick Gessler //=========================================================================== #include #pragma hdrstop #include "Unit1.h" #include //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //=========================================================================== // VARIABLES //=========================================================================== //------------------------------------------------------- PROGRAM STARTS HERE #define CLEAR 0 #define KEY 1 #define CIPHER 2 char c; char *str; int i; int clearLength; int keyLength; int cipherLength; int dec; int clearArray[1000]; int keyArray[1000]; int cipherArray[1000]; // this sets up bitmap graphics variables to hold the pictures. Graphics::TBitmap* pixPlain = new Graphics::TBitmap(); Graphics::TBitmap* pixKey = new Graphics::TBitmap(); Graphics::TBitmap* pixCrypto = new Graphics::TBitmap(); RGBTRIPLE* t; BYTE myByte; AnsiString plainText, KeyText, cryptoText; // cycle counts the steps in a 256 color circuit int cycle = 0; // step counts the steps in the alter .bmp loop int step; bool stop = false; int pixel = 0; int row, column; int times; //=========================================================================== // FUNCTIONS //=========================================================================== //================================================================ ENTER MEMO void enter (int text) { switch (text) { case CLEAR: { Form1->MemoClear->Font->Color = clBlack; char* clearText = new char[ Form1->MemoClear->Text.Length() + 1 ]; strcpy( clearText, Form1->MemoClear->Text.c_str() ); clearLength = StrLen(clearText); Form1->MemoClearASCII->Text = ""; for (int i = 0; i < clearLength; i++) { Form1->EditClearLength->Text = clearLength; char x = clearText[i]; Form1->MemoClearASCII->Text = Form1->MemoClearASCII->Text + " " + IntToStr(x - 31); clearArray[i] = clearText[i] - 31; } break; } case KEY: { Form1->MemoKey->Font->Color = clBlack; char* keyText = new char[ Form1->MemoKey->Text.Length() + 1 ]; strcpy( keyText, Form1->MemoKey->Text.c_str() ); keyLength = StrLen(keyText); Form1->MemoKeyASCII->Text = ""; for (int i = 0; i < keyLength; i++) { Form1->EditKeyLength->Text = keyLength; char x = keyText[i]; Form1->MemoKeyASCII->Text = Form1->MemoKeyASCII->Text + " " + IntToStr(x - 31); keyArray[i] = keyText[i] - 31; } break; } case CIPHER: { Form1->MemoCipher->Font->Color = clBlack; char* cipherText = new char[ Form1->MemoCipher->Text.Length() + 1 ]; strcpy( cipherText, Form1->MemoCipher->Text.c_str() ); cipherLength = StrLen(cipherText); Form1->MemoCipherASCII->Text = ""; for (int i = 0; i < cipherLength; i++) { Form1->EditCipherLength->Text = cipherLength; char x = cipherText[i]; Form1->MemoCipherASCII->Text = Form1->MemoCipherASCII->Text + " " + IntToStr(x - 31); cipherArray[i] = cipherText[i] - 31; } break; } } } //============================================================== EXTRACT MEMO void extract (int text) { switch (text) { case CLEAR: { if (cipherLength <= keyLength) { Form1->MemoClear->Text = ""; Form1->MemoClearASCII->Text = ""; for (int i = 0; i < cipherLength; i++) { clearArray[i] = cipherArray[i] - keyArray[i]; if (clearArray[i] > 96) clearArray[i] -= 96; if (clearArray[i] < 1) clearArray[i] += 96; Form1->MemoClearASCII->Text = Form1->MemoClearASCII->Text + " " + IntToStr(clearArray[i]); c = clearArray[i] + 31; Form1->MemoClear->Text = Form1->MemoClear->Text + c; } } else Form1->MemoClear->Text = "Key Length Too Short"; break; } case KEY: { if (clearLength == cipherLength) { Form1->MemoKey->Text = ""; Form1->MemoKeyASCII->Text = ""; for (int i = 0; i < cipherLength; i++) { keyArray[i] = cipherArray[i] - clearArray[i]; if (keyArray[i] > 96) keyArray[i] -= 96; if (keyArray[i] < 1) keyArray[i] += 96; Form1->MemoKeyASCII->Text = Form1->MemoKeyASCII->Text + " " + IntToStr(keyArray[i]); c = keyArray[i] + 31; Form1->MemoKey->Text = Form1->MemoKey->Text + c; } } else Form1->MemoKey->Text = "Clear and Cipher Lengths Unequal"; break; } case CIPHER: { if (clearLength <= keyLength) { Form1->MemoCipher->Text = ""; Form1->MemoCipherASCII->Text = ""; for (int i = 0; i < clearLength; i++) { cipherArray[i] = clearArray[i] + keyArray[i]; if (cipherArray[i] > 96) cipherArray[i] -= 96; if (cipherArray[i] < 1) cipherArray[i] += 96; Form1->MemoCipherASCII->Text = Form1->MemoCipherASCII->Text + " " + IntToStr(cipherArray[i]); c = cipherArray[i] + 31; Form1->MemoCipher->Text = Form1->MemoCipher->Text + c; } } else Form1->MemoCipher->Text = "Key Length Too Short"; break; } } } //---------------------------------------------------- RENDER BITMAP FUNCTION // This renders the current version of the bitmap to the screen. void renderBMP(Graphics::TBitmap* picture, int paintBox) { // and this is really speedy... switch (paintBox) { case CLEAR: { Form1->PaintBoxPlain->Canvas->Draw(0, 0, picture); break; } case KEY: { Form1->PaintBoxKey->Canvas->Draw(0, 0, picture); break; } case CIPHER: { Form1->PaintBoxCrypto->Canvas->Draw(0, 0, picture); break; } } } //---------------------------------------------------- Insert Bit into Image void insertBit (int bit) { times++; for (int step = 0; step < 256; step++) { // for each row of the image for (row = 0; row < pixPlain->Height; row++) { // t is a color triplet for a pixel t = (RGBTRIPLE*)pixPlain->ScanLine[row]; // for each column in that row of the image for (column = 0; column < pixPlain->Width; column++) { if (1) { t->rgbtRed++; t->rgbtGreen--; t->rgbtBlue++; } else { t->rgbtRed++; t->rgbtGreen--; t->rgbtBlue++; } t++; } } Form1->PaintBoxPlain->Canvas->Draw(0, 0, pixPlain); Application->ProcessMessages(); } } //------------------------------------------------------ Plain Text to Image void plainTextToImage (void) { times = 0; char* plainText = new char[Form1->MemoClear->Text.Length() + 1 ]; strcpy(plainText, Form1->MemoClear->Text.c_str()); for (int i = 1; i < Form1->MemoClear->Text.Length() - 1; i++) { myByte = plainText[i]; if ((myByte & 0x80) == 0x80) insertBit(1); else insertBit(0); if ((myByte & 0x40) == 0x40) insertBit(1); else insertBit(0); if ((myByte & 0x20) == 0x20) insertBit(1); else insertBit(0); if ((myByte & 0x10) == 0x10) insertBit(1); else insertBit(0); if ((myByte & 0x08) == 0x08) insertBit(1); else insertBit(0); if ((myByte & 0x04) == 0x04) insertBit(1); else insertBit(0); if ((myByte & 0x02) == 0x02) insertBit(1); else insertBit(0); if ((myByte & 0x01) == 0x01) insertBit(1); else insertBit(0); } } //=========================================================================== // EVENT HANDLERS //=========================================================================== //------------------------------------------------------------- ON FORM CLOSE void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { // we make sure to delete the memory allocated for the picture delete pixPlain; delete pixKey; delete pixCrypto; } //------------------------------------------------------------- ON FORM PAINT void __fastcall TForm1::FormPaint(TObject *Sender) { renderBMP(pixPlain, CLEAR); renderBMP(pixKey, KEY); renderBMP(pixCrypto, CIPHER); } //--------------------------------------------------------- OPEN CLEAR BUTTON void __fastcall TForm1::ButtonOpenPlainClick(TObject *Sender) { if (OpenPictureDialogPlain->Execute() ) pixPlain->LoadFromFile(OpenPictureDialogPlain->FileName); renderBMP(pixPlain, CLEAR); } //--------------------------------------------------------- SAVE CLEAR BUTTON void __fastcall TForm1::ButtonSavePlainClick(TObject *Sender) { if (SavePictureDialogPlain->Execute() ) pixPlain->SaveToFile(SavePictureDialogPlain->FileName); } //----------------------------------------------------------- OPEN KEY BUTTON void __fastcall TForm1::ButtonOpenKeyClick(TObject *Sender) { if (OpenPictureDialogKey->Execute() ) pixKey->LoadFromFile(OpenPictureDialogKey->FileName); renderBMP(pixKey, KEY); } //----------------------------------------------------------- SAVE KEY BUTTON void __fastcall TForm1::ButtonSaveKeyClick(TObject *Sender) { if (SavePictureDialogKey->Execute() ) pixKey->SaveToFile(SavePictureDialogKey->FileName); } //-------------------------------------------------------- OPEN CIPHER BUTTON void __fastcall TForm1::ButtonOpenCryptoClick(TObject *Sender) { if (OpenPictureDialogCrypto->Execute() ) pixCrypto->LoadFromFile(OpenPictureDialogCrypto->FileName); renderBMP(pixCrypto, CIPHER); } //-------------------------------------------------------- SAVE CIPHER BUTTON void __fastcall TForm1::ButtonSaveCryptoClick(TObject *Sender) { if (SavePictureDialogCrypto->Execute() ) pixCrypto->SaveToFile(SavePictureDialogCrypto->FileName); } //------------------------------------------------ Plain Text To Image Button void __fastcall TForm1::BitBtnPlainTextToImageClick(TObject *Sender) { plainTextToImage(); } //------------------------------------------------ Plain Image To Text Button void __fastcall TForm1::BitBtnPlainImageToTextClick(TObject *Sender) { // } //-------------------------------------------------- Key Text To Image Button void __fastcall TForm1::BitBtnKeyTextToImageClick(TObject *Sender) { // } //-------------------------------------------------- Key Image To Text Button void __fastcall TForm1::BitBtnKeyImageToTextClick(TObject *Sender) { // } //----------------------------------------------- Crypto Text To Image Button void __fastcall TForm1::BitBtnCryptoTextToImageClick(TObject *Sender) { // } //----------------------------------------------- Crypto Image To Text Button void __fastcall TForm1::BitBtnCryptoImageToTextClick(TObject *Sender) { // } void __fastcall TForm1::ButtonEnterClearClick(TObject *Sender) { enter(CLEAR); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonExtractClearClick(TObject *Sender) { extract(CLEAR); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonEnterKeyClick(TObject *Sender) { enter(KEY); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonExtractKeyClick(TObject *Sender) { extract(KEY); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonEnterCipherClick(TObject *Sender) { enter(CIPHER); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonClearCipherClick(TObject *Sender) { extract(CIPHER); } //--------------------------------------------------------------------------- //---------------------------------------------------- MEMO CLEAR TEXT CHANGE void __fastcall TForm1::MemoClearChange(TObject *Sender) { MemoClear->Font->Color = clGray; } //------------------------------------------------------ MEMO KEY TEXT CHANGE void __fastcall TForm1::MemoKeyChange(TObject *Sender) { MemoKey->Font->Color = clGray; } //--------------------------------------------------- MEMO CIPHER TEXT CHANGE void __fastcall TForm1::MemoCipherChange(TObject *Sender) { MemoCipher->Font->Color = clGray; } //---------------------------------------------------------------------------