0

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 */
}
3
  • Formatting please! You could parallelize each loop, but the issue is that your password array is shared by everyone, that cannot work. Commented Nov 30, 2018 at 16:30
  • Thanks for your prompt response. I am unsure of what I should do next. A guide from a pro will really help. As I wrote earlier, I am very new to coding. Thanks! Commented Nov 30, 2018 at 16:34
  • 1
    Start with a simpler task then with OpenMP. Just one simple loop with private variables. Commented Nov 30, 2018 at 16:36

1 Answer 1

1

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;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks @Brice but I got this error: ‘#pragma omp cancel parallel’ construct not closely nested inside of ‘#pragma omp parallel’ after compiling.
You may try omp cancel for and omp cancellation point for instead
Thanks a lot @Brice and everyone that helped out. Much appreciated!
@Brice I which luck could just be in my favor today and you will look into my issue here(stackoverflow.com/questions/67237429/…) then surely my challenges will surely be fixed. Tried following the steps here(with little adjustment) but not working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.