Skip to content

Commit

Permalink
Add HEXL-FPGA compatibility for DyadicMultiply and KeySwitch (#109)
Browse files Browse the repository at this point in the history
Co-authored-by: Tomas Gonzalez Aragon <tomas.gonzalez.aragon@intel.com>
  • Loading branch information
ymeng-git and tgonzalez89-intel authored Mar 11, 2022
1 parent 352e9ed commit fe56a32
Show file tree
Hide file tree
Showing 14 changed files with 211 additions and 54 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ option(HEXL_SHARED_LIB "Generate a shared library" OFF)
option(HEXL_TESTING "Enables unit-tests" ON)
option(HEXL_TREAT_WARNING_AS_ERROR "Treat all compile-time warnings as errors" OFF)

if (NOT HEXL_FPGA_COMPATIBILITY)
set(HEXL_FPGA_COMPATIBILITY "0" CACHE INTERNAL "Set FPGA compatibility mask" FORCE)
endif()

message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")
Expand All @@ -73,6 +77,7 @@ message(STATUS "HEXL_EXPERIMENTAL: ${HEXL_EXPERIMENTAL}")
message(STATUS "HEXL_SHARED_LIB: ${HEXL_SHARED_LIB}")
message(STATUS "HEXL_TESTING: ${HEXL_TESTING}")
message(STATUS "HEXL_TREAT_WARNING_AS_ERROR: ${HEXL_TREAT_WARNING_AS_ERROR}")
message(STATUS "HEXL_FPGA_COMPATIBILITY: ${HEXL_FPGA_COMPATIBILITY}")

hexl_check_compiler_version()
hexl_add_compiler_definition()
Expand Down
17 changes: 15 additions & 2 deletions hexl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ set(NATIVE_SRC

if (HEXL_EXPERIMENTAL)
list(APPEND NATIVE_SRC
experimental/seal/ckks-multiply.cpp
experimental/seal/ckks-switch-key.cpp
experimental/seal/dyadic-multiply.cpp
experimental/seal/key-switch.cpp
experimental/seal/dyadic-multiply-internal.cpp
experimental/seal/key-switch-internal.cpp
experimental/misc/lr-mat-vec-mult.cpp
)
endif()
Expand Down Expand Up @@ -74,6 +76,17 @@ if(CpuFeatures_FOUND)
target_include_directories(hexl PUBLIC ${CpuFeatures_INCLUDE_DIR}) # Public headers
endif()

if (HEXL_FPGA_COMPATIBILITY STREQUAL "1")
target_compile_options(hexl PRIVATE -DHEXL_FPGA_COMPATIBLE_DYADIC_MULTIPLY)
elseif (HEXL_FPGA_COMPATIBILITY STREQUAL "2")
target_compile_options(hexl PRIVATE -DHEXL_FPGA_COMPATIBLE_KEYSWITCH)
elseif (HEXL_FPGA_COMPATIBILITY STREQUAL "3")
target_compile_options(hexl PRIVATE
-DHEXL_FPGA_COMPATIBLE_DYADIC_MULTIPLY
-DHEXL_FPGA_COMPATIBLE_KEYSWITCH
)
endif()

if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(hexl PRIVATE -Wall -Wconversion -Wshadow -pedantic -Wextra
-Wno-unknown-pragmas -march=native -O3 -fomit-frame-pointer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// Copyright (C) 2020-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "hexl/experimental/seal/ckks-multiply.hpp"

#include <cstring>
#include "hexl/experimental/seal/dyadic-multiply-internal.hpp"

#include "hexl/eltwise/eltwise-add-mod.hpp"
#include "hexl/eltwise/eltwise-mult-mod.hpp"
Expand All @@ -14,10 +12,11 @@

namespace intel {
namespace hexl {
namespace internal {

void CkksMultiply(uint64_t* result, const uint64_t* operand1,
const uint64_t* operand2, uint64_t n, const uint64_t* moduli,
uint64_t num_moduli) {
void DyadicMultiply(uint64_t* result, const uint64_t* operand1,
const uint64_t* operand2, uint64_t n,
const uint64_t* moduli, uint64_t num_moduli) {
HEXL_CHECK(result != nullptr, "Require result != nullptr");
HEXL_CHECK(operand1 != nullptr, "Require operand1 != nullptr");
HEXL_CHECK(operand2 != nullptr, "Require operand2 != nullptr");
Expand Down Expand Up @@ -74,5 +73,6 @@ void CkksMultiply(uint64_t* result, const uint64_t* operand1,
}
}

} // namespace internal
} // namespace hexl
} // namespace intel
22 changes: 22 additions & 0 deletions hexl/experimental/seal/dyadic-multiply.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2020-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#ifndef HEXL_FPGA_COMPATIBLE_DYADIC_MULTIPLY

#include "hexl/experimental/seal/dyadic-multiply.hpp"

#include "hexl/experimental/seal/dyadic-multiply-internal.hpp"

namespace intel {
namespace hexl {

void DyadicMultiply(uint64_t* result, const uint64_t* operand1,
const uint64_t* operand2, uint64_t n,
const uint64_t* moduli, uint64_t num_moduli) {
intel::hexl::internal::DyadicMultiply(result, operand1, operand2, n, moduli,
num_moduli);
}

} // namespace hexl
} // namespace intel
#endif
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// Copyright (C) 2020-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include <cstring>
#include "hexl/experimental/seal/key-switch-internal.hpp"

#include <cassert>
#include <exception>
#include <iostream>

#include "hexl/eltwise/eltwise-add-mod.hpp"
#include "hexl/eltwise/eltwise-fma-mod.hpp"
Expand All @@ -16,13 +20,19 @@

namespace intel {
namespace hexl {
namespace internal {

void KeySwitch(uint64_t* result, const uint64_t* t_target_iter_ptr, uint64_t n,
uint64_t decomp_modulus_size, uint64_t key_modulus_size,
uint64_t rns_modulus_size, uint64_t key_component_count,
const uint64_t* moduli, const uint64_t** k_switch_keys,
const uint64_t* modswitch_factors,
const uint64_t* root_of_unity_powers_ptr) {
if (root_of_unity_powers_ptr != nullptr) {
throw std::invalid_argument(
"Parameter root_of_unity_powers_ptr is not supported yet.");
}

void CkksSwitchKey(uint64_t* result, const uint64_t* t_target_iter_ptr,
uint64_t n, uint64_t decomp_modulus_size,
uint64_t key_modulus_size, uint64_t rns_modulus_size,
uint64_t key_component_count, uint64_t* moduli,
const uint64_t** k_switch_keys,
uint64_t* modswitch_factors) {
uint64_t coeff_count = n;

// Create a copy of target_iter
Expand Down Expand Up @@ -193,5 +203,6 @@ void CkksSwitchKey(uint64_t* result, const uint64_t* t_target_iter_ptr,
return;
}

} // namespace internal
} // namespace hexl
} // namespace intel
27 changes: 27 additions & 0 deletions hexl/experimental/seal/key-switch.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2020-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#ifndef HEXL_FPGA_COMPATIBLE_KEYSWITCH

#include "hexl/experimental/seal/key-switch.hpp"

#include "hexl/experimental/seal/key-switch-internal.hpp"

namespace intel {
namespace hexl {

void KeySwitch(uint64_t* result, const uint64_t* t_target_iter_ptr, uint64_t n,
uint64_t decomp_modulus_size, uint64_t key_modulus_size,
uint64_t rns_modulus_size, uint64_t key_component_count,
const uint64_t* moduli, const uint64_t** k_switch_keys,
const uint64_t* modswitch_factors,
const uint64_t* root_of_unity_powers_ptr) {
intel::hexl::internal::KeySwitch(
result, t_target_iter_ptr, n, decomp_modulus_size, key_modulus_size,
rns_modulus_size, key_component_count, moduli, k_switch_keys,
modswitch_factors, root_of_unity_powers_ptr);
}

} // namespace hexl
} // namespace intel
#endif
29 changes: 29 additions & 0 deletions hexl/include/hexl/experimental/seal/dyadic-multiply-internal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (C) 2020-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <cstdint>

namespace intel {
namespace hexl {
namespace internal {

/// @brief Computes dyadic multiplication
/// @param[in,out] result Ciphertext data. Will be over-written with result. Has
/// (2 * n * num_moduli) elements
/// @param[in] operand1 First ciphertext argument. Has (2 * n * num_moduli)
/// elements.
/// @param[in] operand2 Second ciphertext argument. Has (2 * n * num_moduli)
/// elements.
/// @param[in] n Number of coefficients in each polynomial
/// @param[in] moduli Pointer to contiguous array of num_moduli word-sized
/// coefficient moduli
/// @param[in] num_moduli Number of word-sized coefficient moduli
void DyadicMultiply(uint64_t* result, const uint64_t* operand1,
const uint64_t* operand2, uint64_t n,
const uint64_t* moduli, uint64_t num_moduli);

} // namespace internal
} // namespace hexl
} // namespace intel
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace intel {
namespace hexl {

/// @brief Computes CKKS multiplication
/// @brief Computes dyadic multiplication
/// @param[in,out] result Ciphertext data. Will be over-written with result. Has
/// (2 * n * num_moduli) elements
/// @param[in] operand1 First ciphertext argument. Has (2 * n * num_moduli)
Expand All @@ -19,9 +19,9 @@ namespace hexl {
/// @param[in] moduli Pointer to contiguous array of num_moduli word-sized
/// coefficient moduli
/// @param[in] num_moduli Number of word-sized coefficient moduli
void CkksMultiply(uint64_t* result, const uint64_t* operand1,
const uint64_t* operand2, uint64_t n, const uint64_t* moduli,
uint64_t num_moduli);
void DyadicMultiply(uint64_t* result, const uint64_t* operand1,
const uint64_t* operand2, uint64_t n,
const uint64_t* moduli, uint64_t num_moduli);

} // namespace hexl
} // namespace intel
44 changes: 44 additions & 0 deletions hexl/include/hexl/experimental/seal/key-switch-internal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (C) 2020-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <stdint.h>

namespace intel {
namespace hexl {
namespace internal {

/// @brief Computes key switching in-place
/// @param[in,out] result Ciphertext data. Will be over-written with result. Has
/// (n * decomp_modulus_size * key_component_count) elements
/// @param[in] t_target_iter_ptr Pointer to the last component of the input
/// ciphertext
/// @param[in] n Number of coefficients in each polynomial
/// @param[in] decomp_modulus_size Number of moduli in the ciphertext at its
/// current level, excluding one auxiliary prime.
/// @param[in] key_modulus_size Number of moduli in the ciphertext at its top
/// level, including one auxiliary prime.
/// @param[in] rns_modulus_size Number of moduli in the ciphertext at its
/// current level, including one auxiliary prime. rns_modulus_size ==
/// decomp_modulus_size + 1
/// @param[in] key_component_count Number of components in the resulting
/// ciphertext, e.g. key_component_count == 2.
/// @param[in] moduli Array of word-sized coefficient moduli. There must be
/// key_modulus_size moduli in the array
/// @param[in] k_switch_keys Array of evaluation key data. Has
/// decomp_modulus_size entries, each with
/// coeff_count * ((key_modulus_size - 1)+ (key_component_count - 1) *
/// (key_modulus_size) + 1) entries
/// @param[in] modswitch_factors Array of modulus switch factors
/// @param[in] root_of_unity_powers_ptr Array of root of unity powers
void KeySwitch(uint64_t* result, const uint64_t* t_target_iter_ptr, uint64_t n,
uint64_t decomp_modulus_size, uint64_t key_modulus_size,
uint64_t rns_modulus_size, uint64_t key_component_count,
const uint64_t* moduli, const uint64_t** k_switch_keys,
const uint64_t* modswitch_factors,
const uint64_t* root_of_unity_powers_ptr = nullptr);

} // namespace internal
} // namespace hexl
} // namespace intel
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
namespace intel {
namespace hexl {

/// @brief Computes CKKS key switching in-place
/// @brief Computes key switching in-place
/// @param[in,out] result Ciphertext data. Will be over-written with result. Has
/// (n * decomp_modulus_size * key_component_count) elements
/// @param[in] t_target_iter_ptr TODO(fboemer)
/// @param[in] t_target_iter_ptr Pointer to the last component of the input
/// ciphertext
/// @param[in] n Number of coefficients in each polynomial
/// @param[in] decomp_modulus_size Number of moduli in the ciphertext at its
/// current level, excluding one auxiliary prime.
Expand All @@ -20,19 +21,22 @@ namespace hexl {
/// @param[in] rns_modulus_size Number of moduli in the ciphertext at its
/// current level, including one auxiliary prime. rns_modulus_size ==
/// decomp_modulus_size + 1
/// @param[in] key_component_count TODO(fboemer)
/// @param[in] key_component_count Number of components in the resulting
/// ciphertext, e.g. key_component_count == 2.
/// @param[in] moduli Array of word-sized coefficient moduli. There must be
/// key_modulus_size moduli in the array
/// @param[in] kswitch_keys Array of evaluation key data. Has
/// @param[in] k_switch_keys Array of evaluation key data. Has
/// decomp_modulus_size entries, each with
/// coeff_count * ((key_modulus_size - 1)+ (key_component_count - 1) *
/// (key_modulus_size) + 1) entries
/// @param[in] modswitch_factors Array of modulus switch factors
void CkksSwitchKey(uint64_t* result, const uint64_t* t_target_iter_ptr,
uint64_t n, uint64_t decomp_modulus_size,
uint64_t key_modulus_size, uint64_t rns_modulus_size,
uint64_t key_component_count, uint64_t* moduli,
const uint64_t** kswitch_keys, uint64_t* modswitch_factors);
/// @param[in] root_of_unity_powers_ptr Array of root of unity powers
void KeySwitch(uint64_t* result, const uint64_t* t_target_iter_ptr, uint64_t n,
uint64_t decomp_modulus_size, uint64_t key_modulus_size,
uint64_t rns_modulus_size, uint64_t key_component_count,
const uint64_t* moduli, const uint64_t** k_switch_keys,
const uint64_t* modswitch_factors,
const uint64_t* root_of_unity_powers_ptr = nullptr);

} // namespace hexl
} // namespace intel
6 changes: 4 additions & 2 deletions hexl/include/hexl/hexl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
#include "hexl/eltwise/eltwise-reduce-mod.hpp"
#include "hexl/eltwise/eltwise-sub-mod.hpp"
#include "hexl/experimental/misc/lr-mat-vec-mult.hpp"
#include "hexl/experimental/seal/ckks-multiply.hpp"
#include "hexl/experimental/seal/ckks-switch-key.hpp"
#include "hexl/experimental/seal/dyadic-multiply-internal.hpp"
#include "hexl/experimental/seal/dyadic-multiply.hpp"
#include "hexl/experimental/seal/key-switch-internal.hpp"
#include "hexl/experimental/seal/key-switch.hpp"
#include "hexl/logging/logging.hpp"
#include "hexl/ntt/ntt.hpp"
#include "hexl/number-theory/number-theory.hpp"
Expand Down
4 changes: 2 additions & 2 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ set(NATIVE_TEST_SRC main.cpp

if (HEXL_EXPERIMENTAL)
list(APPEND NATIVE_TEST_SRC
experimental/seal/test-ckks-multiply.cpp
experimental/seal/test-ckks-switch-key.cpp
experimental/seal/test-dyadic-multiply.cpp
experimental/seal/test-key-switch.cpp
experimental/misc/test-lr-mat-vec-mult.cpp
)
endif()
Expand Down
Loading

0 comments on commit fe56a32

Please sign in to comment.