I am very new to coding and have manage to put these together from different sources. Code runs in c but I am unable to get to work in OpenMP. I get errors such as getting the correct key once and then the next four (4) or five (5) attempts does not generates the correct key. Any help is very welcome.
This is my code.
#include "omp.h"
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <string.h>
#include <time.h>
void handleErrors(void)
{
ERR_print_errors_fp(stderr);
abort();
}
int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
unsigned char *iv, unsigned char *ciphertext)
{
EVP_CIPHER_CTX *ctx;
int len;
int ciphertext_len;
if (!(ctx = EVP_CIPHER_CTX_new()))
handleErrors();
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
handleErrors();
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
handleErrors();
ciphertext_len = len;
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
handleErrors();
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int main(void)
{
int total_thread, thread_id;
double start_time, end_time;
start_time = omp_get_wtime();
printf("Starting of the program, start_time = %f\n", start_time);
/* A 128 bit key */
unsigned char *key = (unsigned char *)"secret##########";
/* A 128 bit IV */
unsigned char *iv = (unsigned char *)"\x01\x02\x03\x04\x05\x06\x07\x08";
/* Message to be encrypted */
unsigned char *plaintext =
(unsigned char *)"This is a really really top secret!";
/* Buffer for ciphertext. Ensure the buffer is long enough for the
ciphertext which may be longer than the plaintext, dependant on the
* algorithm and mode */
unsigned char ciphertext[128];
unsigned char ciphertextnew[128];
#pragma omp parallel
/* Encrypt the plaintext */
encrypt(plaintext, strlen((char *)plaintext), key, iv, ciphertext);
/* Do something useful with the ciphertext here */
printf("Ciphertext is:\n");
BIO_dump_fp(stdout, (const char *)ciphertext, 16);
/*char pbuffer[1024];*/
char password[17] = "################";
char alphabet[] = "ectres";
// int count;
#pragma omp parallel for
for (int s = 0; s < 6; s++)
{
password[0] = alphabet[s];
for (int t = 0; t < 6; t++)
{
password[1] = alphabet[t];
for (int u = 0; u < 6; u++)
{
password[2] = alphabet[u];
for (int v = 0; v < 6; v++)
{
password[3] = alphabet[v];
for (int w = 0; w < 6; w++)
{
password[4] = alphabet[w];
for (int x = 0; x < 6; x++)
{
password[5] = alphabet[x];
encrypt(plaintext, strlen((char *)plaintext),
password, iv, ciphertextnew);
if (strncmp(ciphertext, ciphertextnew, 16) == 0)
{
printf("\n%s", password);
printf(" Here is the correct key!\n\n");
end_time = omp_get_wtime();
total_thread = omp_get_num_threads();
thread_id = omp_get_thread_num();
printf("\nProgram start = %f\n", start_time);
printf("\nProgram end = %f\n", end_time);
printf("\n\nProgram runtime = %f seconds\n\n",
end_time - start_time);
printf("\nTotal number of threads = %d\n",
total_thread);
exit(0);
}
printf("\n%s", password);
}
}
}
}
}
}
return 0;
}
// add padding to key
void pad(char *s, int length)
{
int l;
l = strlen(s); /* its length */
while (l < length)
{
s[l] = '#'; /* insert a space */
l++;
}
s[l] = '\0'; /* strings needs to be terminated in null */
}
As mentionned by @Matthieu Brucher, you have an issue with password
being shared.
Another one is the exit(0);
statement. You can only parallelize structured-blocks with a single exit point at the bottom (i.e. more or less a statement block without any exit
, return
, goto
...). So the exit statement would not be legit. It seems logical: if a thread hits the exit
, what are the other ones supposed to do? How do they know that they have to exit too?
There are however specific directives to cancel a parallel loop, pretty much what the break;
statement would do. The omp cancel
directive will signal all threads to break from the parallel loop or parallel region. The omp cancellation point
is the point where threads will check if a cancellation has been requested.
You'll have to find where the cancellation point should be put: going there too often has a cost in terms of overhead (putting it in the innermost loop may not be efficient), but not often enough means that a thread may keep running for too long before realizing that it should break from its loop (putting it in the outermost loop means that threads will almost never check for cancellation).
char password_found[17];
int flag_found=0;
#pragma omp parallel shared(password_found,flag_found)
{
char password[17] = "################"; //this is a thread private variable
// These will be done in parallel
#pragma omp for collapse(3)
for (int s = 0; s < 6; s++)
for (int t = 0; t < 6; t++)
for (int u = 0; u < 6; u++)
{
password[0] = alphabet[s];
password[1] = alphabet[t];
password[2] = alphabet[u];
// For every s,t,u, a single thread will loop through these
for (int v = 0; v < 6; v++)
for (int w = 0; w < 6; w++)
for (int x = 0; x < 6; x++)
{
password[3] = alphabet[v];
password[4] = alphabet[w];
password[5] = alphabet[x];
encrypt(plaintext, strlen((char *)plaintext),
password, iv, ciphertextnew);
if (strncmp(ciphertext, ciphertextnew, 16) == 0)
{
printf("\n%s", password);
printf(" Here is the correct key!\n\n");
flag_found=1;
strcpy(password_found,password); // Copy thread-private copy to shared variable
// Now, signal everyone to stop
#pragma omp cancel parallel
}
printf("\n%s is bad", password);
} // end inner group of loops
// Threads will check here is they should stop
#pragma omp cancellation point parallel
} // end of the outer group of loops
} // end of parallel region
// Do something now //
if (flag_found){
printf("\nThe password is %s\n",password_found);
return 0;
}else{
printf("Password not found\n");
return 1;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加