SERIAL DATA ENCRYPTION WITH 128-BIT PC1 ALGORITHM
Quote from james789 on March 21, 2024, 9:09 pmSending encrypted data between two Mega328s using the 128-bit PC1 encryption algorithm.
Based on the example of SimuleIDE 1.0.0: Mega328_usart which send a counter between two Mega328s.The PC1 algorithm is available in many different languages , this allows the data to be sent to a computer as well.
http://pccipher.free.fr/pc1/index.html
The data is encrypted with a 128-bit key and then sent over the serial port one byte at a time and decrypted on the other Mega328.
One can view the encrypted data by opening the serial monitor.PROGRAM:
The program (in Arduino C) uses a PC1.h header file.
/* SENDER */ /* Send encrypted counter from mega328 to mega328 */ /* To view encrypted data open Serial Monitor and Print: Value */ /* The key must be same at sender and recevier */ #include "pc1.h" byte data; void setup() { DDRB = 0xFF; PORTB = 0; Serial.begin(9600); data = 0; // 128-bit key // unsigned char crypt_key[16]={0xD4,0xB7,0xE3,0xE8,0x88,0x4C,0x3C,0x54,0x95,0x3F,0x71,0xAA,0x42,0x75,0xBA,0xD1}; for (int i=0;i<16;i++) key[i]=crypt_key[i]; initPc1(); } void loop() { dataCrypt=data; cryptPc1(0); /* 0 = crypt 1 = decrypt */ Serial.write( dataCrypt ); PORTB = data; data++; delay( 500 ); } /* RECEIVER */ /* Receive and decrypt counter from mega328 */ /* To view encrypted data open Serial Monitor and Print: Value */ /* The key must be same at sender and recevier */ #include "pc1.h" volatile byte data; void setup() { DDRB = 0xFF; PORTB = 0; Serial.begin(9600); data = 0; // 128-bit key // unsigned char crypt_key[16]={0xD4,0xB7,0xE3,0xE8,0x88,0x4C,0x3C,0x54,0x95,0x3F,0x71,0xAA,0x42,0x75,0xBA,0xD1}; for (int i=0;i<16;i++) key[i]=crypt_key[i]; initPc1(); } void loop() { if( Serial.available() ) { data = Serial.read(); dataCrypt=data; cryptPc1(1); /* 0 = crypt 1 = decrypt */ data=dataCrypt; PORTB = data; } } /* PC1.H file */ /* PC1 Encryption Cipher 128-bit key */ unsigned int sum1 = 0; unsigned int sum2 = 0; unsigned int keyXorVal = 0; unsigned int j, curByte; unsigned short wkey[8]; unsigned int i; unsigned char dataCrypt; unsigned char key[16]; void initPc1() { for (i = 0; i < 8; i++) { wkey[i] = (key[i * 2] << 8) | key[i * 2 + 1]; } } void cryptPc1(int decryption) { unsigned int temp1 = 0; unsigned int byteXorVal = 0; for (j = 0; j < 8; j++) { temp1 ^= wkey[j]; sum2 = (sum2 + j) * 20021 + sum1; sum1 = (temp1 * 346) & 0xFFFF; sum2 = (sum2 + sum1) & 0xFFFF; temp1 = (temp1 * 20021 + 1) & 0xFFFF; byteXorVal ^= temp1 ^ sum2; } curByte = dataCrypt; if (!decryption) { keyXorVal = curByte * 257; } curByte = ((curByte ^ (byteXorVal >> 8)) ^ byteXorVal) & 0xFF; if (decryption) { keyXorVal = curByte * 257; } for (j = 0; j < 8; j++) { wkey[j] ^= keyXorVal; } dataCrypt = curByte; }
Sending encrypted data between two Mega328s using the 128-bit PC1 encryption algorithm.
Based on the example of SimuleIDE 1.0.0: Mega328_usart which send a counter between two Mega328s.
The PC1 algorithm is available in many different languages , this allows the data to be sent to a computer as well.
http://pccipher.free.fr/pc1/index.html
The data is encrypted with a 128-bit key and then sent over the serial port one byte at a time and decrypted on the other Mega328.
One can view the encrypted data by opening the serial monitor.
PROGRAM:
The program (in Arduino C) uses a PC1.h header file.
/* SENDER */
/* Send encrypted counter from mega328 to mega328 */
/* To view encrypted data open Serial Monitor and Print: Value */
/* The key must be same at sender and recevier */
#include "pc1.h"
byte data;
void setup()
{
DDRB = 0xFF;
PORTB = 0;
Serial.begin(9600);
data = 0;
// 128-bit key //
unsigned char crypt_key[16]={0xD4,0xB7,0xE3,0xE8,0x88,0x4C,0x3C,0x54,0x95,0x3F,0x71,0xAA,0x42,0x75,0xBA,0xD1};
for (int i=0;i<16;i++) key[i]=crypt_key[i];
initPc1();
}
void loop()
{
dataCrypt=data;
cryptPc1(0); /* 0 = crypt 1 = decrypt */
Serial.write( dataCrypt );
PORTB = data;
data++;
delay( 500 );
}
/* RECEIVER */
/* Receive and decrypt counter from mega328 */
/* To view encrypted data open Serial Monitor and Print: Value */
/* The key must be same at sender and recevier */
#include "pc1.h"
volatile byte data;
void setup()
{
DDRB = 0xFF;
PORTB = 0;
Serial.begin(9600);
data = 0;
// 128-bit key //
unsigned char crypt_key[16]={0xD4,0xB7,0xE3,0xE8,0x88,0x4C,0x3C,0x54,0x95,0x3F,0x71,0xAA,0x42,0x75,0xBA,0xD1};
for (int i=0;i<16;i++) key[i]=crypt_key[i];
initPc1();
}
void loop()
{
if( Serial.available() )
{
data = Serial.read();
dataCrypt=data;
cryptPc1(1); /* 0 = crypt 1 = decrypt */
data=dataCrypt;
PORTB = data;
}
}
/* PC1.H file */
/* PC1 Encryption Cipher 128-bit key */
unsigned int sum1 = 0;
unsigned int sum2 = 0;
unsigned int keyXorVal = 0;
unsigned int j, curByte;
unsigned short wkey[8];
unsigned int i;
unsigned char dataCrypt;
unsigned char key[16];
void initPc1()
{
for (i = 0; i < 8; i++) {
wkey[i] = (key[i * 2] << 8) | key[i * 2 + 1];
}
}
void cryptPc1(int decryption)
{
unsigned int temp1 = 0;
unsigned int byteXorVal = 0;
for (j = 0; j < 8; j++) {
temp1 ^= wkey[j];
sum2 = (sum2 + j) * 20021 + sum1;
sum1 = (temp1 * 346) & 0xFFFF;
sum2 = (sum2 + sum1) & 0xFFFF;
temp1 = (temp1 * 20021 + 1) & 0xFFFF;
byteXorVal ^= temp1 ^ sum2;
}
curByte = dataCrypt;
if (!decryption) {
keyXorVal = curByte * 257;
}
curByte = ((curByte ^ (byteXorVal >> 8)) ^ byteXorVal) & 0xFF;
if (decryption) {
keyXorVal = curByte * 257;
}
for (j = 0; j < 8; j++) {
wkey[j] ^= keyXorVal;
}
dataCrypt = curByte;
}
Uploaded files: