diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..00873a7 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,11 @@ +# https://docs.codecov.io/docs/codecovyml-reference + +# We have 2 parallel jobs in ci.yml +codecov: + notify: + after_n_builds: 2 +comment: + after_n_builds: 2 + +github_checks: + annotations: false diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index bcdb51a..5d9a413 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -13,4 +13,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }} # optional - run: julia -e 'using CompatHelper; CompatHelper.main()' + run: julia -e 'using CompatHelper; CompatHelper.main(; subdirs=["", "docs", "test"])' diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml new file mode 100644 index 0000000..3af6956 --- /dev/null +++ b/.github/workflows/Documenter.yml @@ -0,0 +1,24 @@ +name: Documentation + +on: + push: + branches: + - main + tags: '*' + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@latest + with: + version: '1.5' + - name: Install dependencies + run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()' + - name: Build and deploy + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key + run: julia --project=docs/ docs/make.jl diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e0e3c9..edea1fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,12 +73,12 @@ jobs: fail_ci_if_error: true # optional (default = false) # verbose: true # optional (default = false) - finish: - needs: test - runs-on: ubuntu-latest - steps: - - name: Coveralls Finished - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - parallel-finished: true + # finish: + # needs: test + # runs-on: ubuntu-latest + # steps: + # - name: Coveralls Finished + # uses: coverallsapp/github-action@master + # with: + # github-token: ${{ secrets.GITHUB_TOKEN }} + # parallel-finished: true diff --git a/README.md b/README.md index acead14..89f4bb9 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ After installation, load SEAL.jl by running ```julia using SEAL ``` -in the REPL. A **minimal** working example for encrypting an integer using the BFV +in the REPL. A **minimal** working example for encrypting an array of integers using the BFV scheme, squaring it, and decrypting it, looks as follows: ```julia julia> using SEAL [ Info: Precompiling SEAL [bac81e26-86e4-4b48-8696-7d0406d5dbc1] -julia> parms = EncryptionParameters(SchemeType.BFV) +julia> parms = EncryptionParameters(SchemeType.bfv) EncryptionParameters(Ptr{Nothing} @0x0000000002e1d3a0) julia> poly_modulus_degree = 4096 @@ -62,7 +62,7 @@ EncryptionParameters(Ptr{Nothing} @0x0000000002e1d3a0) julia> set_coeff_modulus!(parms, coeff_modulus_bfv_default(poly_modulus_degree)) EncryptionParameters(Ptr{Nothing} @0x0000000002e1d3a0) -julia> set_plain_modulus!(parms, 512) +julia> set_plain_modulus!(parms, plain_modulus_batching(poly_modulus_degree, 20)) EncryptionParameters(Ptr{Nothing} @0x0000000002e1d3a0) julia> context = SEALContext(parms) @@ -88,32 +88,53 @@ Evaluator(Ptr{Nothing} @0x000000000428bdd0) julia> decryptor = Decryptor(context, secret_key_) Decryptor(Ptr{Nothing} @0x00000000037670d0) -julia> encoder = IntegerEncoder(context) #FIXME fix-tests -IntegerEncoder(Ptr{Nothing} @0x0000000002ec3350, SEALContext(Ptr{Nothing} @0x0000000004298440)) #FIXME fix-tests +julia> batch_encoder = BatchEncoder(context) +BatchEncoder(Ptr{Nothing} @0x0000000001fb4bd0, SEALContext(Ptr{Nothing} @0x0000000001b87780)) -julia> value = 7 -7 +julia> pod_matrix = collect(UInt64, 1:slot_count(batch_encoder)); -julia> plain = encode(value, encoder) #FIXME fix-tests +julia> Int.(vcat(pod_matrix[1:3], pod_matrix[end-3:end])) +7-element Array{Int64,1}: + 1 + 2 + 3 + 4093 + 4094 + 4095 + 4096 + +julia> plain_matrix = Plaintext() Plaintext(Ptr{Nothing} @0x00000000042db6e0) -julia> encrypted = Ciphertext() -Ciphertext(Ptr{Nothing} @0x0000000002d91b80) +julia> encode!(plain_matrix, pod_matrix, batch_encoder) +Plaintext(Ptr{Nothing} @0x0000000002ce0370) -julia> encrypt!(encrypted, plain, encryptor) +julia> encrypted_matrix = Ciphertext() Ciphertext(Ptr{Nothing} @0x0000000002d91b80) -julia> square_inplace!(encrypted, evaluator) +julia> encrypt!(encrypted_matrix, plain_matrix, encryptor) Ciphertext(Ptr{Nothing} @0x0000000002d91b80) +julia> add_inplace!(encrypted_matrix, encrypted_matrix, evaluator) +Ciphertext(Ptr{Nothing} @0x0000000002ce1280) + julia> plain_result = Plaintext() Plaintext(Ptr{Nothing} @0x0000000004591550) -julia> decrypt!(plain_result, encrypted, decryptor) +julia> decrypt!(plain_result, encrypted_matrix, decryptor) Plaintext(Ptr{Nothing} @0x0000000004591550) -julia> decode_int32(plain_result, encoder) #FIXME fix-tests -49 +julia> decode!(pod_matrix, plain_result, batch_encoder); + +julia> Int.(vcat(pod_matrix[1:3], pod_matrix[end-3:end])) +7-element Array{Int64,1}: + 2 + 4 + 6 + 8186 + 8188 + 8190 + 8192 ``` ### Examples @@ -128,7 +149,7 @@ directory. Otherwise it will be very likely that you are using SEAL.jl (and SEAL way that is either not secure, will produce unexpected results, or just crashes. The examples included in SEAL.jl follow almost line-by-line the examples provided by the [SEAL library](https://github.com/microsoft/SEAL/tree/master/native/examples). -For example, the snippet above is based on the `example_integer_encoder()` function in #FIXME fix-tests +For example, the snippet above is based on the `example_batch_encoder()` function in [`examples/2_encoders.jl`](examples/2_encoders.jl). The full list of examples is as follows: @@ -155,7 +176,7 @@ julia --project=. -e 'include("SEAL.jl/examples/examples.jl"); seal_examples()' You will be shown an interactive prompt that lets you run any of the available examples: ``` -Microsoft SEAL version: 3.5.5 +Microsoft SEAL version: 3.6.2 +---------------------------------------------------------+ | The following examples should be executed while reading | | comments in associated files in examples/. | diff --git a/docs/src/index.md b/docs/src/index.md index 9bf0715..510fb03 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -38,13 +38,13 @@ After installation, load SEAL.jl by running ```julia using SEAL ``` -in the REPL. A **minimal** working example for encrypting an integer using the BFV +in the REPL. A **minimal** working example for encrypting an array of integers using the BFV scheme, squaring it, and decrypting it, looks as follows: ```julia julia> using SEAL [ Info: Precompiling SEAL [bac81e26-86e4-4b48-8696-7d0406d5dbc1] -julia> parms = EncryptionParameters(SchemeType.BFV) +julia> parms = EncryptionParameters(SchemeType.bfv) EncryptionParameters(Ptr{Nothing} @0x0000000002e1d3a0) julia> poly_modulus_degree = 4096 @@ -56,7 +56,7 @@ EncryptionParameters(Ptr{Nothing} @0x0000000002e1d3a0) julia> set_coeff_modulus!(parms, coeff_modulus_bfv_default(poly_modulus_degree)) EncryptionParameters(Ptr{Nothing} @0x0000000002e1d3a0) -julia> set_plain_modulus!(parms, 512) +julia> set_plain_modulus!(parms, plain_modulus_batching(poly_modulus_degree, 20)) EncryptionParameters(Ptr{Nothing} @0x0000000002e1d3a0) julia> context = SEALContext(parms) @@ -82,32 +82,53 @@ Evaluator(Ptr{Nothing} @0x000000000428bdd0) julia> decryptor = Decryptor(context, secret_key_) Decryptor(Ptr{Nothing} @0x00000000037670d0) -julia> encoder = IntegerEncoder(context) #FIXME fix-tests -IntegerEncoder(Ptr{Nothing} @0x0000000002ec3350, SEALContext(Ptr{Nothing} @0x0000000004298440)) #FIXME fix-tests +julia> batch_encoder = BatchEncoder(context) +BatchEncoder(Ptr{Nothing} @0x0000000001fb4bd0, SEALContext(Ptr{Nothing} @0x0000000001b87780)) -julia> value = 7 -7 +julia> pod_matrix = collect(UInt64, 1:slot_count(batch_encoder)); -julia> plain = encode(value, encoder) +julia> Int.(vcat(pod_matrix[1:3], pod_matrix[end-3:end])) +7-element Array{Int64,1}: + 1 + 2 + 3 + 4093 + 4094 + 4095 + 4096 + +julia> plain_matrix = Plaintext() Plaintext(Ptr{Nothing} @0x00000000042db6e0) -julia> encrypted = Ciphertext() -Ciphertext(Ptr{Nothing} @0x0000000002d91b80) +julia> encode!(plain_matrix, pod_matrix, batch_encoder) +Plaintext(Ptr{Nothing} @0x0000000002ce0370) -julia> encrypt!(encrypted, plain, encryptor) +julia> encrypted_matrix = Ciphertext() Ciphertext(Ptr{Nothing} @0x0000000002d91b80) -julia> square_inplace!(encrypted, evaluator) +julia> encrypt!(encrypted_matrix, plain_matrix, encryptor) Ciphertext(Ptr{Nothing} @0x0000000002d91b80) +julia> add_inplace!(encrypted_matrix, encrypted_matrix, evaluator) +Ciphertext(Ptr{Nothing} @0x0000000002ce1280) + julia> plain_result = Plaintext() Plaintext(Ptr{Nothing} @0x0000000004591550) -julia> decrypt!(plain_result, encrypted, decryptor) +julia> decrypt!(plain_result, encrypted_matrix, decryptor) Plaintext(Ptr{Nothing} @0x0000000004591550) -julia> decode_int32(plain_result, encoder) -49 +julia> decode!(pod_matrix, plain_result, batch_encoder); + +julia> Int.(vcat(pod_matrix[1:3], pod_matrix[end-3:end])) +7-element Array{Int64,1}: + 2 + 4 + 6 + 8186 + 8188 + 8190 + 8192 ``` ### Examples @@ -122,7 +143,7 @@ directory. Otherwise it will be very likely that you are using SEAL.jl (and SEAL way that is either not secure, will produce unexpected results, or just crashes. The examples included in SEAL.jl follow almost line-by-line the examples provided by the [SEAL library](https://github.com/microsoft/SEAL/tree/master/native/examples). -For example, the snippet above is based on the `example_integer_encoder()` function in # FIXME fix-tests +For example, the snippet above is based on the `example_batch_encoder()` function in [`examples/2_encoders.jl`](https://github.com/JuliaCrypto/SEAL.jl/tree/main/examples/2_encoders.jl). The full list of examples is as follows: @@ -149,7 +170,7 @@ julia --project=. -e 'include("SEAL.jl/examples/examples.jl"); seal_examples()' You will be shown an interactive prompt that lets you run any of the available examples: ``` -Microsoft SEAL version: 3.5.5 +Microsoft SEAL version: 3.6.2 +---------------------------------------------------------+ | The following examples should be executed while reading | | comments in associated files in examples/. | diff --git a/examples/7_performance.jl b/examples/7_performance.jl index a3047d6..7276989 100644 --- a/examples/7_performance.jl +++ b/examples/7_performance.jl @@ -97,7 +97,7 @@ function bfv_performance_test(context) encrypt!(encrypted1, plain1, encryptor) encrypted2 = Ciphertext(context) encode!(plain2, fill(UInt64(i+1), slot_count_), batch_encoder) - encrypt!(encrypted2, plain2, encryptor) #FIXME fix-tests + encrypt!(encrypted2, plain2, encryptor) time_add_sum += @elapsedus begin add_inplace!(encrypted1, encrypted1, evaluator) add_inplace!(encrypted2, encrypted2, evaluator) diff --git a/src/SEAL.jl b/src/SEAL.jl index 5478472..488969e 100644 --- a/src/SEAL.jl +++ b/src/SEAL.jl @@ -11,28 +11,33 @@ Abstract parent type for all types based on SEAL classes. abstract type SEALObject end """ - handle(object::SEALObject) + gethandle(object::SEALObject) Return the raw C pointer to where `object` resides in memory. """ -@inline handle(object::SEALObject) = object.handle @inline gethandle(object::SEALObject) = object.handle + +""" + sethandle!(object::SEALObject, handle) + +Set the underlying raw C pointer to where `object` resides in memory to `handle`. +""" @inline sethandle!(object::SEALObject, handle) = object.handle = handle """ - destroy(object::SEALObject) + destroy!(object::SEALObject) Call the corresponding destruction function on `object` to free up memory and reset object handle to -a null pointer. If `object` is not allocated, `destroy` will not do anything. +a null pointer. If `object` is not allocated, `destroy!` will not do anything. """ -function destroy(object::SEALObject) end +function destroy!(object::SEALObject) end """ isnull(object::SEALObject) Return true if the object handle is a null pointer and false otherwise. """ -@inline isnull(object::SEALObject) = handle(object) == C_NULL +@inline isnull(object::SEALObject) = gethandle(object) == C_NULL """ isallocated(object::SEALObject) @@ -41,9 +46,9 @@ Return true if the object is allocated, i.e., if it is not null. """ @inline isallocated(object::SEALObject) = !isnull(object) -export SEALObject, handle, destroy, isnull, isallocated +export SEALObject, gethandle, sethandle!, destroy!, isnull, isallocated -Base.unsafe_convert(::Type{Ptr{Cvoid}}, object::SEALObject) = handle(object) +Base.unsafe_convert(::Type{Ptr{Cvoid}}, object::SEALObject) = gethandle(object) include("auxiliary.jl") # Julia-only auxiliary methods -> no exports diff --git a/src/batchencoder.jl b/src/batchencoder.jl index ef7d91f..99515d4 100644 --- a/src/batchencoder.jl +++ b/src/batchencoder.jl @@ -14,15 +14,18 @@ mutable struct BatchEncoder <: SEALObject function BatchEncoder(handle::Ptr{Cvoid}, context) object = new(handle, context) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::BatchEncoder) +function destroy!(object::BatchEncoder) if isallocated(object) - ccall((:BatchEncoder_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:BatchEncoder_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function slot_count(encoder::BatchEncoder) diff --git a/src/ciphertext.jl b/src/ciphertext.jl index f309c3e..61c4fba 100644 --- a/src/ciphertext.jl +++ b/src/ciphertext.jl @@ -33,15 +33,18 @@ mutable struct Ciphertext <: SEALObject function Ciphertext(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::Ciphertext) +function destroy!(object::Ciphertext) if isallocated(object) - ccall((:Ciphertext_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:Ciphertext_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function scale(encrypted::Ciphertext) diff --git a/src/ckks.jl b/src/ckks.jl index c06b0e7..bad5419 100644 --- a/src/ckks.jl +++ b/src/ckks.jl @@ -23,15 +23,18 @@ mutable struct CKKSEncoder <: SEALObject function CKKSEncoder(handle::Ptr{Cvoid}, context) object = new(handle, context) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::CKKSEncoder) +function destroy!(object::CKKSEncoder) if isallocated(object) - ccall((:CKKSEncoder_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:CKKSEncoder_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end """ diff --git a/src/context.jl b/src/context.jl index 67ee2dc..51070be 100644 --- a/src/context.jl +++ b/src/context.jl @@ -22,15 +22,18 @@ mutable struct SEALContext <: SEALObject function SEALContext(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::SEALContext) +function destroy!(object::SEALContext) if isallocated(object) - ccall((:SEALContext_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:SEALContext_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function first_parms_id(context::SEALContext) @@ -112,15 +115,18 @@ mutable struct ContextData <: SEALObject function ContextData(handle::Ptr{Cvoid}; destroy_on_gc=true) object = new(handle) - destroy_on_gc && finalizer(destroy, object) + destroy_on_gc && finalizer(destroy!, object) return object end end -function destroy(object::ContextData) +function destroy!(object::ContextData) if isallocated(object) - ccall((:ContextData_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:ContextData_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function chain_index(context_data::ContextData) @@ -183,15 +189,18 @@ mutable struct EncryptionParameterQualifiers <: SEALObject function EncryptionParameterQualifiers(handle::Ptr{Cvoid}; destroy_on_gc=true) object = new(handle) - destroy_on_gc && finalizer(destroy, object) + destroy_on_gc && finalizer(destroy!, object) return object end end -function destroy(object::EncryptionParameterQualifiers) +function destroy!(object::EncryptionParameterQualifiers) if isallocated(object) - ccall((:EncryptionParameterQualifiers_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:EncryptionParameterQualifiers_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function using_batching(epq::EncryptionParameterQualifiers) diff --git a/src/decryptor.jl b/src/decryptor.jl index fbbe5f7..3cef0a5 100644 --- a/src/decryptor.jl +++ b/src/decryptor.jl @@ -20,15 +20,18 @@ mutable struct Decryptor <: SEALObject function Decryptor(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::Decryptor) +function destroy!(object::Decryptor) if isallocated(object) - ccall((:Decryptor_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:Decryptor_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function decrypt!(destination::Plaintext, encrypted::Ciphertext, decryptor::Decryptor) diff --git a/src/encryptionparams.jl b/src/encryptionparams.jl index 79ebd8e..8a7bcfe 100644 --- a/src/encryptionparams.jl +++ b/src/encryptionparams.jl @@ -34,15 +34,18 @@ mutable struct EncryptionParameters <: SEALObject function EncryptionParameters(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::EncryptionParameters) +function destroy!(object::EncryptionParameters) if isallocated(object) - ccall((:EncParams_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:EncParams_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function poly_modulus_degree(enc_param::EncryptionParameters) @@ -63,7 +66,7 @@ function set_poly_modulus_degree!(enc_param::EncryptionParameters, degree) end function set_coeff_modulus!(enc_param::EncryptionParameters, coeff_modulus) - coeff_modulus_ptrs = Ptr{Cvoid}[handle(c) for c in coeff_modulus] + coeff_modulus_ptrs = Ptr{Cvoid}[gethandle(c) for c in coeff_modulus] retval = ccall((:EncParams_SetCoeffModulus, libsealc), Clong, (Ptr{Cvoid}, UInt64, Ref{Ptr{Cvoid}}), enc_param, length(coeff_modulus), coeff_modulus_ptrs) diff --git a/src/encryptor.jl b/src/encryptor.jl index 36464b2..a012d27 100644 --- a/src/encryptor.jl +++ b/src/encryptor.jl @@ -38,15 +38,18 @@ mutable struct Encryptor <: SEALObject function Encryptor(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::Encryptor) +function destroy!(object::Encryptor) if isallocated(object) - ccall((:Encryptor_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:Encryptor_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function set_secret_key!(encryptor::Encryptor, secret_key::SecretKey) diff --git a/src/evaluator.jl b/src/evaluator.jl index 15cc94d..96d8379 100644 --- a/src/evaluator.jl +++ b/src/evaluator.jl @@ -21,15 +21,18 @@ mutable struct Evaluator <: SEALObject function Evaluator(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::Evaluator) +function destroy!(object::Evaluator) if isallocated(object) - ccall((:Evaluator_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:Evaluator_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function square!(destination::Ciphertext, encrypted::Ciphertext, evaluator::Evaluator) diff --git a/src/galoiskeys.jl b/src/galoiskeys.jl index 464d662..9d2996f 100644 --- a/src/galoiskeys.jl +++ b/src/galoiskeys.jl @@ -21,15 +21,18 @@ mutable struct GaloisKeys <: SEALObject function GaloisKeys(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::GaloisKeys) +function destroy!(object::GaloisKeys) if isallocated(object) - ccall((:KSwitchKeys_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:KSwitchKeys_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function parms_id(key::GaloisKeys) diff --git a/src/keygenerator.jl b/src/keygenerator.jl index 55cf583..6dc656d 100644 --- a/src/keygenerator.jl +++ b/src/keygenerator.jl @@ -22,15 +22,18 @@ mutable struct KeyGenerator <: SEALObject function KeyGenerator(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::KeyGenerator) +function destroy!(object::KeyGenerator) if isallocated(object) - ccall((:KeyGenerator_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:KeyGenerator_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function create_public_key!(destination::PublicKey, keygen::KeyGenerator) @@ -41,7 +44,7 @@ function create_public_key!(destination::PublicKey, keygen::KeyGenerator) @check_return_value retval # Destroy previous key and reuse its container - destroy(destination) + destroy!(destination) sethandle!(destination, keyptr[]) return nothing @@ -73,7 +76,7 @@ function create_relin_keys!(destination::RelinKeys, keygen::KeyGenerator) @check_return_value retval # Destroy previous key and reuse its container - destroy(destination) + destroy!(destination) sethandle!(destination, keyptr[]) return nothing @@ -96,7 +99,7 @@ function create_galois_keys!(destination::GaloisKeys, keygen::KeyGenerator) @check_return_value retval # Destroy previous key and reuse its container - destroy(destination) + destroy!(destination) sethandle!(destination, keyptr[]) return nothing diff --git a/src/memorymanager.jl b/src/memorymanager.jl index ceb0f1c..a6a5d96 100644 --- a/src/memorymanager.jl +++ b/src/memorymanager.jl @@ -4,15 +4,18 @@ mutable struct MemoryPoolHandle <: SEALObject function MemoryPoolHandle(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::MemoryPoolHandle) +function destroy!(object::MemoryPoolHandle) if isallocated(object) - ccall((:MemoryPoolHandle_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:MemoryPoolHandle_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function alloc_byte_count(handle::MemoryPoolHandle) diff --git a/src/modulus.jl b/src/modulus.jl index c59bc24..a2e0cc5 100644 --- a/src/modulus.jl +++ b/src/modulus.jl @@ -22,16 +22,19 @@ mutable struct Modulus <: SEALObject function Modulus(handle::Ptr{Cvoid}; destroy_on_gc=true) object = new(handle) if destroy_on_gc - finalizer(destroy, object) + finalizer(destroy!, object) end return object end end -function destroy(object::Modulus) +function destroy!(object::Modulus) if isallocated(object) - ccall((:Modulus_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:Modulus_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end module SecLevelType diff --git a/src/plaintext.jl b/src/plaintext.jl index 37a5230..5812b04 100644 --- a/src/plaintext.jl +++ b/src/plaintext.jl @@ -40,15 +40,18 @@ mutable struct Plaintext <: SEALObject function Plaintext(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::Plaintext) +function destroy!(object::Plaintext) if isallocated(object) - ccall((:Plaintext_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:Plaintext_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function scale(plain::Plaintext) diff --git a/src/publickey.jl b/src/publickey.jl index cfc7814..3a62915 100644 --- a/src/publickey.jl +++ b/src/publickey.jl @@ -20,15 +20,18 @@ mutable struct PublicKey <: SEALObject function PublicKey(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::PublicKey) +function destroy!(object::PublicKey) if isallocated(object) - ccall((:PublicKey_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:PublicKey_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function parms_id(key::PublicKey) diff --git a/src/relinkeys.jl b/src/relinkeys.jl index 66875ad..356da5a 100644 --- a/src/relinkeys.jl +++ b/src/relinkeys.jl @@ -21,15 +21,18 @@ mutable struct RelinKeys <: SEALObject function RelinKeys(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::RelinKeys) +function destroy!(object::RelinKeys) if isallocated(object) - ccall((:KSwitchKeys_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:KSwitchKeys_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function parms_id(key::RelinKeys) diff --git a/src/secretkey.jl b/src/secretkey.jl index 65a9d24..f589e1e 100644 --- a/src/secretkey.jl +++ b/src/secretkey.jl @@ -20,15 +20,18 @@ mutable struct SecretKey <: SEALObject function SecretKey(handle::Ptr{Cvoid}) object = new(handle) - finalizer(destroy, object) + finalizer(destroy!, object) return object end end -function destroy(object::SecretKey) +function destroy!(object::SecretKey) if isallocated(object) - ccall((:SecretKey_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + @check_return_value ccall((:SecretKey_Destroy, libsealc), Clong, (Ptr{Cvoid},), object) + sethandle!(object, C_NULL) end + + return nothing end function parms_id(key::SecretKey) diff --git a/test/test_extra.jl b/test/test_extra.jl index 74d1efb..0a55015 100644 --- a/test/test_extra.jl +++ b/test/test_extra.jl @@ -56,9 +56,9 @@ @test_throws ErrorException SEAL.check_return_value(0x11111111) end - @testset "destroy" begin + @testset "destroy!" begin mempool = memory_manager_get_pool() - @test_nowarn destroy(mempool) + @test_nowarn destroy!(mempool) end end