Борется с шифрованием RSA на CUDA - PullRequest
0 голосов
/ 17 апреля 2019

Я пытаюсь ускорить шифрование с использованием алгоритма RSA с использованием CUDA.Я не могу правильно выполнить power-modulo в функции ядра.

Я использую инструменты компиляции Cuda в AWS, выпуск 9.0, V9.0.176 для компиляции.

#include <cstdio>
#include <math.h>
#include "main.h"

// Kernel function to encrypt the message (m_in) elements into cipher (c_out)
__global__
void enc(int numElements, int e, int n, int *m_in, int *c_out)
{
    int index = blockIdx.x * blockDim.x + threadIdx.x;
    int stride = blockDim.x * gridDim.x;

    printf("e = %d, n = %d, numElements = %d\n", e, n, numElements);
    for (int i = index; i < numElements; i += stride)
    {
// POINT OF ERROR //
        // c_out[i] = (m_in[i]^e) % n;     //**GIVES WRONG RESULTS**
         c_out[i] = __pow(m_in[i], e) % n; //**GIVES, error: expression must have integral or enum type**
    }


}
// This function is called from main() from other file.
int* cuda_rsa(int numElements, int* data, int public_key, int key_length)
{
    int e = public_key;
    int n = key_length;

    // Allocate Unified Memory – accessible from CPU or GPU
    int* message_array;
    cudaMallocManaged(&message_array, numElements*sizeof(int));
    int* cipher_shared_array;       //Array shared by CPU and GPU
    cudaMallocManaged(&cipher_shared_array, numElements*sizeof(int));

    int* cipher_array = (int*)malloc(numElements * sizeof(int));

    //Put message array to be encrypted in a managed array
    for(int i=0; i<numElements; i++)
    {
        message_array[i] = data[i];
    }

    // Run kernel on 16M elements on the GPU
    enc<<<1, 1>>>(numElements, e, n, message_array, cipher_shared_array);

    // Wait for GPU to finish before accessing on host
    cudaDeviceSynchronize();

    //Copy into a host array and pass it to main() function for verification. 
    //Ignored memory leaks.
    for(int i=0; i<numElements; i++)
    {
        cipher_array[i] = cipher_shared_array[i];
    }
    return (cipher_array);
}

Пожалуйста, помогите мне с этой ошибкой.Как я могу реализовать power-modulo (как показано ниже) в ядре CUDA?

(x ^ y) % n;

Буду очень признателен за любую помощь.

1 Ответ

1 голос
/ 17 апреля 2019

В C или C ++ это:

(x^y) 

не повышает x до степени y. Выполняет побитовую исключающую-или-операцию .Вот почему ваша первая реализация не дает правильного ответа.

В C или C ++ арифметический оператор по модулю:

%

определен только для целочисленных аргументов ,Даже если вы передаете целые числа в функцию __pow(), возвращаемый результат этой функции - double (т. Е. Величина с плавающей запятой, а не целое число).

Я не знаю,детали математики, которые вам нужно выполнить, но если вы приведете результат __pow к int (например), эта ошибка компиляции исчезнет. Это может или не может быть действительным для любой арифметики, которую вы хотите выполнить .(Например, вы можете привести его к «длинному» целому числу.)

После этого вы столкнетесь с другой ошибкой компиляции.Самый простой подход - использовать pow() вместо __pow():

c_out[i] = (int)pow(m_in[i], e) % n;

Если вы на самом деле пытались использовать встроенную в CUDA fast-math , вам следует использовать __powfnot __pow:

c_out[i] = (int)__powf(m_in[i], e) % n;

Обратите внимание, что встроенные математические функции обычно имеют пониженную точность.

Поскольку эти функции повышения мощности выполняют арифметику с плавающей запятой (даже если выпередавая целые числа) можно получить некоторые неожиданные результаты.Например, если вы повысите 5 до степени 2, можно получить 24.9999999999 вместо 25. Если вы просто приведете это к целому числу, вы получите усечение до 24. Поэтому вам может потребоваться изучить округление результата доближайшее целое число, вместо приведения.Но опять же, я не изучал математику, которую вы хотите выполнить.

...