diff --git a/native/src/seal/c/polyarray.cpp b/native/src/seal/c/polyarray.cpp index 2019ddf6..f643e949 100644 --- a/native/src/seal/c/polyarray.cpp +++ b/native/src/seal/c/polyarray.cpp @@ -77,7 +77,32 @@ SEAL_C_FUNC PolynomialArray_CreateFromPublicKey(void *memoryPoolHandle, void *co } } -SEAL_C_FUNC PolynomialArray_Copy(void *copy, void **poly_array) { +SEAL_C_FUNC PolynomialArray_CreateFromSecretKey( + void *memoryPoolHandle, void *context, void *secret_key, void **poly_array) +{ + const SEALContext *ctx = FromVoid(context); + IfNullRet(ctx, E_POINTER); + + const SecretKey *sk = FromVoid(secret_key); + IfNullRet(sk, E_POINTER); + + IfNullRet(poly_array, E_POINTER); + unique_ptr handle = MemHandleFromVoid(memoryPoolHandle); + + try + { + PolynomialArray *array = new PolynomialArray(*ctx, *sk, *handle); + *poly_array = array; + return S_OK; + } + catch (const invalid_argument &) + { + return E_INVALIDARG; + } +} + +SEAL_C_FUNC PolynomialArray_Copy(void *copy, void **poly_array) +{ PolynomialArray *copyptr = FromVoid(copy); IfNullRet(copyptr, E_POINTER); IfNullRet(poly_array, E_POINTER); diff --git a/native/src/seal/c/polyarray.h b/native/src/seal/c/polyarray.h index 35da53a1..42dcb637 100644 --- a/native/src/seal/c/polyarray.h +++ b/native/src/seal/c/polyarray.h @@ -9,6 +9,8 @@ SEAL_C_FUNC PolynomialArray_CreateFromCiphertext(void *memoryPoolHandle, void *c SEAL_C_FUNC PolynomialArray_CreateFromPublicKey(void *memoryPoolHandle, void *context, void *public_key, void **poly_array); +SEAL_C_FUNC PolynomialArray_CreateFromSecretKey(void *memoryPoolHandle, void *context, void *secret_key, void **poly_array); + SEAL_C_FUNC PolynomialArray_Copy(void *copy, void **poly_array); SEAL_C_FUNC PolynomialArray_Destroy(void *thisptr); diff --git a/native/src/seal/polyarray.cpp b/native/src/seal/polyarray.cpp index 0f82a89c..835f9d9b 100644 --- a/native/src/seal/polyarray.cpp +++ b/native/src/seal/polyarray.cpp @@ -82,11 +82,41 @@ namespace seal } } + PolynomialArray::PolynomialArray( + const SEALContext &context, + const SecretKey &secret_key, + MemoryPoolHandle pool + ) : PolynomialArray(pool) { + + auto &pt = secret_key.data(); + auto &parms = context.first_context_data()->parms(); + auto &plain_modulus = parms.plain_modulus(); + auto &coeff_modulus = parms.coeff_modulus(); + auto coeff_modulus_size = coeff_modulus.size(); + auto poly_modulus_degree = pt.coeff_count(); + + auto is_ntt_form = pt.is_ntt_form(); + size_t coeff_count = parms.poly_modulus_degree(); + auto &context_data = *context.get_context_data(parms.parms_id()); + auto ntt_tables = context_data.small_ntt_tables(); + + reserve(1, poly_modulus_degree, {plain_modulus}); + + const auto data_ptr = pt.data(); + insert_polynomial(0, data_ptr); + + // Convert out of NTT form for each polynomial. + if (is_ntt_form) { + for (size_t i = 0; i < coeff_modulus_size; i++) { + inverse_ntt_negacyclic_harvey(get_polynomial(0) + i * coeff_count, ntt_tables[i]); + } + } + } + PolynomialArray::PolynomialArray(const PolynomialArray ©): PolynomialArray(copy.pool_) { // These parameters in the result object are internally stored once // reserve is called. auto poly_size = copy.poly_size(); - auto coeff_modulus_size = copy.coeff_modulus_size(); auto coeff_modulus = copy.coeff_modulus_; auto poly_modulus_degree = copy.poly_modulus_degree(); diff --git a/native/src/seal/polyarray.h b/native/src/seal/polyarray.h index c021ca4d..b4c345c0 100644 --- a/native/src/seal/polyarray.h +++ b/native/src/seal/polyarray.h @@ -4,6 +4,7 @@ #include "seal/ciphertext.h" #include "seal/memorymanager.h" #include "seal/publickey.h" +#include "seal/secretkey.h" #include using namespace seal::util; @@ -45,6 +46,13 @@ namespace seal const SEALContext &context, const PublicKey &public_key, MemoryPoolHandle pool ); + /** + Create a PolynomialArray from a secret key. + */ + PolynomialArray( + const SEALContext &context, const SecretKey &secret_key, MemoryPoolHandle pool + ); + /** Creates a new ciphertext by copying a given one.