home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
comm
/
term23_2.lha
/
Source_Code
/
termSource
/
termCrypt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-18
|
6KB
|
294 lines
/*
** $Id: termCrypt.c,v 1.3 92/08/15 20:13:50 olsen Sta Locker: olsen $
** $Revision: 1.3 $
** $Date: 92/08/15 20:13:50 $
**
** Data encryption routines
**
** Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
#include "termGlobal.h"
/* The width of the cell ring is defined here. A word of warning: never
* encrypt a file and forget the access password, since it will be
* extremely hard to break the code (with 30 cells there are 256^30
* possible values each cell may be initialized to which means that
* you could have to try more than 1.7e+72 combinations for each single
* password character before actually finding the matching password).
* See `Random sequence generation by cellular automata' by Steven
* Wolfram (Institute for Advanced Study; Advances in Applied
* Mathematics) for more information.
*/
#define CELL_WIDTH 30
/* The cell ring and the ring index pointers. */
STATIC UBYTE Cell[2][CELL_WIDTH + 2],From,To;
/* The pattern the cell ring will be filled with. The pattern
* may seem familiar: these are the first 32 digits of Pi.
*/
STATIC UBYTE Pi[32] = { 3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5 };
/* Automaton():
*
* A cellular automaton working on a ring of celles, producing
* random data in each single cell .
*/
STATIC UBYTE
Automaton()
{
register WORD i;
/* Operate on the cell ring... */
for(i = 1 ; i <= CELL_WIDTH ; i++)
Cell[To][i] = Cell[From][i - 1] ^ (Cell[From][i] | Cell[From][i + 1]);
/* Operate on first and last element. */
Cell[To][0] = Cell[From][CELL_WIDTH + 1] ^ (Cell[From][0] | Cell[From][1]);
Cell[To][CELL_WIDTH + 1] = Cell[From][CELL_WIDTH] ^ (Cell[From][CELL_WIDTH + 1] | Cell[From][0]);
/* Swap cell rings. */
To = From;
From ^= 1;
/* Return contents of first cell. */
return(Cell[From][0]);
}
/* Encrypt(UBYTE *Source,UBYTE *Destination,UBYTE *Key):
*
* Encrypt data using cellular automaton as a random number generator.
*/
UBYTE *
Encrypt(UBYTE *Source,WORD SourceLen,UBYTE *Destination,UBYTE *Key,WORD KeyLen,BYTE Prefill)
{
register WORD i,j;
/* Set up cell ring index pointers. */
From = 0;
To = 1;
if(Prefill)
{
memcpy(&Cell[0][KeyLen],Pi,32 - KeyLen);
memcpy(Cell[0],Key,KeyLen);
}
else
{
/* Initialize the cell ring with the key contents. */
for(i = 0 , j = KeyLen - 1 ; i < CELL_WIDTH + 2 ; i++)
{
Cell[0][i] = Key[j];
if(j)
j--;
else
j = KeyLen - 1;
}
}
/* Encrypt the source data. */
for(i = 0 ; i < SourceLen ; i++)
Destination[i] = ((WORD)Source[i] + Automaton()) % 256;
/* Return result. */
return(Destination);
}
/* Decrypt(UBYTE *Source,UBYTE *Destination,UBYTE *Key):
*
* Decrypt data using cellular automaton as a random number generator.
*/
UBYTE *
Decrypt(UBYTE *Source,WORD SourceLen,UBYTE *Destination,UBYTE *Key,WORD KeyLen,BYTE Prefill)
{
register WORD i,j,Code;
/* Set up cell ring index pointers. */
From = 0;
To = 1;
if(Prefill)
{
memcpy(&Cell[0][KeyLen],Pi,32 - KeyLen);
memcpy(Cell[0],Key,KeyLen);
}
else
{
/* Initialize the cell ring with the key contents. */
for(i = 0 , j = KeyLen - 1 ; i < CELL_WIDTH + 2 ; i++)
{
Cell[0][i] = Key[j];
if(j)
j--;
else
j = KeyLen - 1;
}
}
/* Decrypt the source data. */
for(i = 0 ; i < SourceLen ; i++)
{
if((Code = Source[i] - Automaton()) < 0)
Code = 256 + Code;
Destination[i] = Code;
}
/* Return result. */
return(Destination);
}
/* CryptPanel(UBYTE *Buffer):
*
* Ask the user to enter an access password, do not display
* it while typing.
*/
BYTE
CryptPanel(UBYTE *Buffer)
{
STATIC struct IntuiText IText[] =
{
1,0,JAM1,30,19,&DefaultFont,NULL, &IText[1],
1,0,JAM1,46,28,&DefaultFont,NULL, NULL
};
struct Window *PanelWindow;
BYTE Result = FALSE,FgPen;
IText[0] . IText = LocaleString(MSG_TERMCRYPT_PLEASE_ENTER_ACCESS_PASSWORD_TXT);
IText[1] . IText = LocaleString(MSG_TERMCRYPT_PRESS_RETURN_WHEN_DONE_TXT);
switch(Config . ColourMode)
{
case COLOUR_EIGHT: FgPen = 7;
break;
case COLOUR_SIXTEEN: FgPen = 15;
break;
case COLOUR_AMIGA: if(Config . DisableBlinking & TERMINAL_FASTER)
FgPen = 1;
else
FgPen = 2;
break;
case COLOUR_MONO: FgPen = 1;
break;
}
IText[0] . FrontPen = IText[1] . FrontPen = FgPen;
if(PanelWindow = OpenWindowTags(NULL,
WA_Width, 294,
WA_Height, 46,
WA_Left, (Screen -> Width - 294) >> 1,
WA_Top, (Screen -> Height - 46) >> 1,
WA_Activate, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_RMBTrap, TRUE,
WA_CustomScreen,Screen,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY,
WA_Title, LocaleString(MSG_TERMCRYPT_ENTER_PASSWORD_TXT),
TAG_DONE))
{
struct IntuiMessage *Massage;
ULONG Class,Code;
BYTE Terminated = FALSE,
Count = 0;
PrintIText(PanelWindow -> RPort,&IText[0],0,0);
DrawBevelBox(PanelWindow -> RPort,8,13,PanelWindow -> Width - 16,PanelWindow -> Height - (13 + 5),
GT_VisualInfo, VisualInfo,
GTBB_Recessed, TRUE,
TAG_DONE);
while(!Terminated)
{
WaitPort(PanelWindow -> UserPort);
while(!Terminated && (Massage = (struct IntuiMessage *)GetMsg(PanelWindow -> UserPort)))
{
Class = Massage -> Class;
Code = Massage -> Code;
ReplyMsg(Massage);
if(Class == IDCMP_CLOSEWINDOW)
Terminated = TRUE;
if(Class == IDCMP_VANILLAKEY)
{
switch(Code)
{
case '\033': Terminated = TRUE;
break;
case '\r': Terminated = TRUE;
if(Count)
Result = TRUE;
break;
case '\b': if(Count)
Buffer[Count--] = 0;
else
DisplayBeep(PanelWindow -> WScreen);
break;
default: if((Code >= ' ' && Code < 127) || Code >= 160)
{
Buffer[Count++] = Code;
if(Count == 20)
Terminated = Result = TRUE;
}
else
DisplayBeep(PanelWindow -> WScreen);
break;
}
}
}
}
CloseWindow(PanelWindow);
}
return(Result);
}