Currently I am trying to use MPI to pass a particular encrypted data from one processor to another using only 2 processor to just check if encryption or decryption is working. I have an int value which is converted to string for encryption and then sent to processor rank 1. I am receiving the string correctly in processor but when I call the decryption function it seems to not give me the plaintext. I have downloaded the AES code from https://github.com/kokke/tiny-AES-C
int size,rank;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
int data = 532123;
uint8_t data_file[10];
uint8_t key[1] = {50};
int data_decrypt;
uint8_t iv[1] = {1};
struct AES_ctx ctx;
if (rank == 0) {
sprintf((char *) data_file, "%d", data);
AES_init_ctx_iv(&ctx, key, iv);
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen((char *) data_file));
printf("Sending in 0: %s\n",(char*) data_file);
MPI_Send(data_file,10,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,10,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1: %s\n",(char*)data_file);
AES_init_ctx_iv(&ctx, key, iv);
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen((char*)data_file));
printf("DEC at Rank 1: %s\n",(char*) data_file);
}
MPI_Finalize();
return 0;
First of all we must install requirements. see this link
After successfully install the requirements we run simple hello world MPI.
Hello World!
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
// Initialize the MPI environment
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// Print off a hello world message
printf("Hello world from processor %s, rank %d out of %d processors\n",
processor_name, world_rank, world_size);
// Finalize the MPI environment.
MPI_Finalize();
}
Compile and Run
$ mpicc mhello.c -o mhello
$ mpirun -np #numberOfProcess ./mhello
After successful run this code you can go further.
And return to original Question.
I think your usage of AES part of project is wrong.
By performing some changes and use
AES_ECB_decrypt(&ctx, data_file);
AES_ECB_encrypt(&ctx, data_file);
works.
GitHub page of project say how to use Enc and Dec function see
Second important change to use struct AES_ctx ctx;
above main to only one time execution.
This is working version of code.
mpi-hello.c
#include <stdio.h>
#include <string.h>
#include <mpi.h>
#include "aes.h"
/*
* compile
* mpicc mpi-hello.c aes.c -o mpi-hello
*
* Run
* mpirun -np 2 executable
*
*
*
* */
struct AES_ctx ctx;
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
int main(int argc, char** argv) {
int size,rank=0;
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int data = 532123;
uint8_t data_file[10];
printf("this is in main\n");
if (rank == 0) {
printf("data rank: 0: %d\n", data);
//convert in to string
sprintf( data_file, "%d", data);
//string
printf("data rank: 0: %s\n", data_file);
//encrypt data
AES_ECB_encrypt(&ctx, data_file);
printf("Sending in 0 after crypt: %s\n", data_file);
printf("strlen send: %d\n", strlen(data_file));
MPI_Send(data_file,16,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,16,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1 before: %s\n",data_file);
printf("strlen recv: %d\n", strlen(data_file));
AES_ECB_decrypt(&ctx, data_file);
printf("DEC at Rank 1 string: %s\n", data_file);
printf("DEC at Rank 1 int: %u\n", ToUInt(data_file));
}
MPI_Finalize();
}
Important notes
aes.c
source file in same folder of original source i.e: mpi-hello.c
compile the code with mpicc mpi-hello.c aes.c -o mpi-hello
run with: mpirun -np 2 ./mpi-hello
MPI_Send
must be changed to 16
, But why?PS.
Installing from repository on Debian based system not works and i have to build it from source.
Original source of convert string to int I know this may not best solution but works.
How to run MPI.
Edit 1
#include <stdio.h>
#include <string.h>
#include <mpi.h>
#include "aes.h"
/*
* compile
* mpicc mpi-hello.c aes.c -o mpi-hello
*
* Run
* mpirun -np 2 executable
*
*
*
* */
struct AES_ctx ctx;
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
int main(int argc, char** argv) {
int size,rank=0;
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int data = 532123;
uint8_t data_file[10];
printf("this is in main\n");
if (rank == 0) {
printf("data rank: 0: %d\n", data);
//convert in to string
sprintf( data_file, "%d", data);
//string
printf("data rank: 0: %s\n", data_file);
//encrypt data
//AES_ECB_encrypt(&ctx, data_file);
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("Sending in 0 after crypt: %s\n", data_file);
printf("strlen send: %d\n", strlen(data_file));
MPI_Send(data_file,10,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,10,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1 before: %s\n",data_file);
printf("strlen recv: %d\n", strlen(data_file));
//AES_ECB_decrypt(&ctx, data_file);
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("DEC at Rank 1 string: %s\n", data_file);
printf("DEC at Rank 1 int: %u\n", ToUInt(data_file));
}
MPI_Finalize();
}
Edit 2
Apply request in comment.
#include <stdio.h>
#include <string.h>
#include <mpi.h>
#include "aes.h"
/*
* compile
* mpicc mpi-hello.c aes.c -o mpi-hello
*
* Run
* mpirun -np 2 executable
*
*
* */
unsigned long ToUInt(char* str)
{
unsigned long mult = 1;
unsigned long re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
int main(int argc, char** argv) {
int size,rank=0;
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int data = 532123;
uint8_t data_file[10];
//start Crypto Section
//~ key and iv
///
uint8_t key[32] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
uint8_t iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
///
struct AES_ctx ctx;
printf("this is in main\n");
if (rank == 0) {
printf("data rank: 0: %d\n", data);
//convert in to string
sprintf( data_file, "%d", data);
//string
printf("data rank: 0: %s\n", data_file);
///Enc
//set
AES_init_ctx_iv(&ctx, key, iv);
//enc
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("Sending in 0 after crypt: %s\n", data_file);
printf("strlen send: %d\n", strlen(data_file));
MPI_Send(data_file,10,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,10,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1 before: %s\n",data_file);
printf("strlen recv: %d\n", strlen(data_file));
///Dec
//set
AES_init_ctx_iv(&ctx, key, iv);
//dec
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("DEC at Rank 1 string: %s\n", data_file);
printf("DEC at Rank 1 int: %u\n", ToUInt(data_file));
}
MPI_Finalize();
}
Edit 3
Place key and iv in if else section.
if (rank == 0) {
printf("data rank: 0: %d\n", data);
//convert in to string
sprintf( data_file, "%d", data);
//string
printf("data rank: 0: %s\n", data_file);
//~ key and iv
///
uint8_t key[32] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
uint8_t iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
///
///Enc
//set
AES_init_ctx_iv(&ctx, key, iv);
//enc
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("Sending in 0 after crypt: %s\n", data_file);
printf("strlen send: %d\n", strlen(data_file));
MPI_Send(data_file,10,MPI_UINT8_T,1,0,MPI_COMM_WORLD);
}else{
MPI_Recv(data_file,10,MPI_UINT8_T,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("Recieved in 1 before: %s\n",data_file);
printf("strlen recv: %d\n", strlen(data_file));
//~ key and iv
///
uint8_t key[32] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
uint8_t iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
///
///Dec
//set
AES_init_ctx_iv(&ctx, key, iv);
//dec
AES_CTR_xcrypt_buffer(&ctx, data_file, strlen(data_file));
printf("DEC at Rank 1 string: %s\n", data_file);
printf("DEC at Rank 1 int: %u\n", ToUInt(data_file));
}
For example You can change first element of key i.e: 0x60 -> 0x61
in either if or else not both, then recompile and run the program to see if receiver haven't correct key he/she cant decode your encrypted data.
[ToDo]