Вектор точка продукта в Microsoft SEAL с CKKS - PullRequest
2 голосов
/ 13 февраля 2020

В настоящее время я пытаюсь реализовать методы умножения матриц с использованием библиотеки Microsoft SEAL. Я создал vector<vector<double>> в качестве входной матрицы и закодировал ее CKKSEncoder. Однако кодер упаковывает весь вектор в один Plaintext, поэтому у меня просто есть vector<Plaintext>, который заставляет меня потерять 2D-структуру (и тогда, конечно, у меня будет vector<Ciphertext> после шифрования). Наличие 1D-вектора позволяет мне получить доступ только к строкам, но не к столбцам.

Мне удалось транспонировать матрицы перед кодированием. Это позволило мне умножить по компонентам строки первой матрицы и столбцы (строки в транспонированной форме) второй матрицы, но я не могу суммировать элементы результирующего вектора вместе, так как он упакован в один зашифрованный текст. Мне просто нужно выяснить, как заставить произведение векторной точки работать в SEAL для умножения матриц. Я что-то упустил или мой метод неверен?

Ответы [ 2 ]

0 голосов
/ 17 февраля 2020

KyoohyungHan предложил в выпуске: https://github.com/microsoft/SEAL/issues/138, что можно решить проблему с вращениями, вращая выходной вектор и суммируя его многократно.

Для пример:

// my_output_vector is the Ciphertext output

vector<Ciphertext> rotations_output(my_output_vector.size());

for(int steps = 0; steps < my_output_vector.size(); steps++)
{
    evaluator.rotate_vector(my_output_vector, steps, galois_keys, rotations_output[steps]);
}

Ciphertext sum_output;
evaluator.add_many(rotations_output, sum_output);
0 голосов
/ 13 февраля 2020

вектор векторов не совпадает с массивом массивов (2D, матрица).

В то время как одномерный vector<double>.data() указывает на непрерывное пространство памяти (например, вы можете сделать memcpy на этом ) каждый из «подвекторов» выделяет собственный, отдельный буфер памяти. Поэтому vector<vector<double>>.data() не имеет смысла и не может использоваться в качестве матрицы.

В C ++ двумерный массив array2D[W][H] хранится в памяти идентично array[W*H]. Поэтому оба могут обрабатываться одними и теми же процедурами (когда это имеет смысл). Рассмотрим следующий пример:

void fill_array(double *array, size_t size, double value) {
    for (size_t i = 0; i < size; ++i) {
        array[i] = value;
    }
}

int main(int argc, char *argv[])
{
    constexpr size_t W = 10;
    constexpr size_t H = 5;
    double matrix[W][H];
    // using 2D array as 1D to fill all elements with 5.
    fill_array(&matrix[0][0], W * H, 5);
    for (const auto &row: matrix) {
        for (const auto v : row) {
            cout << v << '\t';
        }
        cout << '\n';
    }

    return 0;
}

В приведенном выше примере вы можете заменить double matrix[W][H]; на vector<double> matrix(W * H); и ввести matrix.data() в fill_array(). Однако вы не можете объявить вектор (W) для вектора (H).

PS Существует множество реализаций математического вектора и матрицы на языке C ++. Вы можете использовать один из них, если не хотите иметь дело с массивами C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...