Skip to content

Commit

Permalink
Merge pull request #4 from JuliaCrypto/msl/6_serialization
Browse files Browse the repository at this point in the history
examples/6_serialization
  • Loading branch information
sloede authored Jul 5, 2020
2 parents b3c2a49 + a698b0f commit 70b87d2
Show file tree
Hide file tree
Showing 11 changed files with 643 additions and 7 deletions.
180 changes: 180 additions & 0 deletions examples/6_serialization.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
include("utilities.jl")

using SEAL
using Printf


function example_serialization()
print_example_banner("Example: Serialization")

parms_stream = UInt8[]
data_stream1 = UInt8[]
data_stream2 = UInt8[]
data_stream3 = UInt8[]
data_stream4 = UInt8[]
sk_stream = UInt8[]

# Use `let` to create new variable scope to mimic curly braces-delimited blocks in C++

# Server
let
enc_parms = EncryptionParameters(SchemeType.CKKS)
poly_modulus_degree = 8192
set_poly_modulus_degree!(enc_parms, poly_modulus_degree)
set_coeff_modulus!(enc_parms, coeff_modulus_create(poly_modulus_degree, [50, 20, 50]))

resize!(parms_stream, save_size(enc_parms))
out_bytes = save!(parms_stream, enc_parms)
resize!(parms_stream, out_bytes)

print_line(@__LINE__)
println("EncryptionParameters: wrote ", out_bytes, " bytes")

print_line(@__LINE__)
println("EncryptionParameters: data size upper bound (compr_mode_type::none): ",
save_size(ComprModeType.none, enc_parms))
println(" EncryptionParameters: data size upper bound (compr_mode_type::deflate): ",
save_size(ComprModeType.deflate, enc_parms))

byte_buffer = Vector{UInt8}(undef, save_size(enc_parms))
save!(byte_buffer, length(byte_buffer), enc_parms)

enc_parms2 = EncryptionParameters()
load!(enc_parms2, byte_buffer, length(byte_buffer))

print_line(@__LINE__)
println("EncryptionParameters: parms == parms2: ", enc_parms == enc_parms2)
end

# Client
let
enc_parms = EncryptionParameters()
load!(enc_parms, parms_stream)

context = SEALContext(enc_parms)

keygen = KeyGenerator(context)
pk = public_key(keygen)
sk = secret_key(keygen)

resize!(sk_stream, save_size(sk))
out_bytes = save!(sk_stream, sk)
resize!(sk_stream, out_bytes)

rlk = relin_keys(keygen)

resize!(data_stream1, save_size(rlk))
size_rlk = save!(data_stream1, rlk)
resize!(data_stream1, size_rlk)

rlk_local = relin_keys_local(keygen)
resize!(data_stream2, save_size(rlk_local))
size_rlk_local = save!(data_stream2, rlk_local)
resize!(data_stream2, size_rlk_local)

print_line(@__LINE__)
println("Serializable<RelinKeys>: wrote ", size_rlk, " bytes")
println(" ", "RelinKeys (local): wrote ", size_rlk_local, " bytes")

initial_scale = 2.0^20
encoder = CKKSEncoder(context)
plain1 = Plaintext()
plain2 = Plaintext()
encode!(plain1, 2.3, initial_scale, encoder)
encode!(plain2, 4.5, initial_scale, encoder)

encryptor = Encryptor(context, pk)
encrypted1 = Ciphertext()
encrypted2 = Ciphertext()
encrypt!(encrypted1, plain1, encryptor)
encrypt!(encrypted2, plain2, encryptor)

sym_encryptor = Encryptor(context, sk)
sym_encrypted1 = encrypt_symmetric(plain1, sym_encryptor)
sym_encrypted2 = encrypt_symmetric(plain2, sym_encryptor)

resize!(data_stream2, save_size(sym_encrypted1))
size_sym_encrypted1 = save!(data_stream2, sym_encrypted1)
resize!(data_stream2, size_sym_encrypted1)
resize!(data_stream3, save_size(encrypted1))
size_encrypted1 = save!(data_stream3, encrypted1)
resize!(data_stream3, size_encrypted1)

print_line(@__LINE__)
println("Serializable<Ciphertext> (symmetric-key): wrote ", size_sym_encrypted1, " bytes")
println(" ", "Ciphertext (public-key): wrote ", size_encrypted1, " bytes")

resize!(data_stream3, save_size(sym_encrypted2))
size_sym_encrypted2 = save!(data_stream3, sym_encrypted2)
resize!(data_stream3, size_sym_encrypted2)
end

# Server
let
enc_parms = EncryptionParameters()
load!(enc_parms, parms_stream)
context = SEALContext(enc_parms)

evaluator = Evaluator(context)

rlk = RelinKeys()
encrypted1 = Ciphertext()
encrypted2 = Ciphertext()

load!(rlk, context, data_stream1)
load!(encrypted1, context, data_stream2)
load!(encrypted2, context, data_stream3)

encrypted_prod = Ciphertext()
multiply!(encrypted_prod, encrypted1, encrypted2, evaluator)
relinearize_inplace!(encrypted_prod, rlk, evaluator)
rescale_to_next_inplace!(encrypted_prod, evaluator)

resize!(data_stream4, save_size(encrypted_prod))
size_encrypted_prod = save!(data_stream4, encrypted_prod)
resize!(data_stream4, size_encrypted_prod)

print_line(@__LINE__)
println("Ciphertext (symmetric-key): wrote ", size_encrypted_prod, " bytes")
end

# Client
let
enc_parms = EncryptionParameters()
load!(enc_parms, parms_stream)
context = SEALContext(enc_parms)

sk = SecretKey()
load!(sk, context, sk_stream)
decryptor = Decryptor(context, sk)
encoder = CKKSEncoder(context)

encrypted_result = Ciphertext()
load!(encrypted_result, context, data_stream4)

plain_result = Plaintext()
decrypt!(plain_result, encrypted_result, decryptor)
slot_count_ = slot_count(encoder)
result = Vector{Float64}(undef, slot_count_)
decode!(result, plain_result, encoder)

print_line(@__LINE__)
println("Result: ")
print_vector(result, 3, 7)
end

pt = Plaintext("1x^2 + 3")
stream = Vector{UInt8}(undef, save_size(pt))
data_size = save!(stream, pt)
resize!(stream, data_size)

header = SEALHeader()
load_header!(header, stream)

print_line(@__LINE__)
println("Size written to stream: ", data_size, " bytes")
println(" ", "Size indicated in SEALHeader: ", header.size, " bytes")
println()

return
end
16 changes: 10 additions & 6 deletions src/SEAL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ export version_major, version_minor, version_patch, version
include("modulus.jl")
export Modulus, SecLevelType, bit_count, value, coeff_modulus_create, coeff_modulus_bfv_default

include("serialization.jl")
export ComprModeType, SEALHeader, load_header!

include("encryptionparams.jl")
export EncryptionParameters, SchemeType, get_poly_modulus_degree,
set_poly_modulus_degree!, set_coeff_modulus!, coeff_modulus,
scheme, plain_modulus, set_plain_modulus!, plain_modulus_batching, parms_id
scheme, plain_modulus, set_plain_modulus!, plain_modulus_batching, parms_id, save!,
save_size, load!

include("context.jl")
export SEALContext, first_parms_id, last_parms_id, get_context_data, key_context_data,
Expand All @@ -46,25 +50,25 @@ include("publickey.jl")
export PublicKey, parms_id

include("secretkey.jl")
export SecretKey, parms_id
export SecretKey, parms_id, save!, load!

include("galoiskeys.jl")
export GaloisKeys, parms_id

include("relinkeys.jl")
export RelinKeys, parms_id
export RelinKeys, parms_id, save_size, save!, load!

include("keygenerator.jl")
export KeyGenerator, public_key, secret_key, relin_keys_local, relin_keys, galois_keys_local

include("plaintext.jl")
export Plaintext, scale, scale!, parms_id, to_string
export Plaintext, scale, scale!, parms_id, to_string, save_size, save!

include("ciphertext.jl")
export Ciphertext, scale, scale!, parms_id, size, length
export Ciphertext, scale, scale!, parms_id, size, length, save_size, save!, load!

include("encryptor.jl")
export Encryptor, encrypt!
export Encryptor, encrypt!, encrypt_symmetric, encrypt_symmetric!

include("evaluator.jl")
export Evaluator, square!, square_inplace!, relinearize!, relinearize_inplace!, rescale_to_next!,
Expand Down
38 changes: 38 additions & 0 deletions src/ciphertext.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,41 @@ function Base.size(encrypted::Ciphertext)
end
Base.length(encrypted::Ciphertext) = size(encrypted)[1]

function save_size(compr_mode, encrypted::Ciphertext)
result = Ref{Int64}(0)
retval = ccall((:Ciphertext_SaveSize, libsealc), Clong,
(Ptr{Cvoid}, UInt8, Ref{Int64}),
encrypted, compr_mode, result)
@check_return_value retval
return Int(result[])
end
save_size(encrypted::Ciphertext) = save_size(ComprModeType.default, encrypted)

function save!(buffer::DenseVector{UInt8}, length::Integer,
compr_mode::ComprModeType.ComprModeTypeEnum, encrypted::Ciphertext)
out_bytes = Ref{Int64}(0)
retval = ccall((:Ciphertext_Save, libsealc), Clong,
(Ptr{Cvoid}, Ref{UInt8}, UInt64, UInt8, Ref{Int64}),
encrypted, buffer, length, compr_mode, out_bytes)
@check_return_value retval
return Int(out_bytes[])
end
function save!(buffer::DenseVector{UInt8}, length::Integer, encrypted::Ciphertext)
return save!(buffer, length, ComprModeType.default, encrypted)
end
function save!(buffer::DenseVector{UInt8}, encrypted::Ciphertext)
return save!(buffer, length(buffer), encrypted)
end

function load!(encrypted::Ciphertext, context::SEALContext, buffer::DenseVector{UInt8}, length)
in_bytes = Ref{Int64}(0)
retval = ccall((:Ciphertext_Load, libsealc), Clong,
(Ptr{Cvoid}, Ptr{Cvoid}, Ref{UInt8}, UInt64, Ref{Int64}),
encrypted, context, buffer, length, in_bytes)
@check_return_value retval
return Int(in_bytes[])
end
function load!(encrypted::Ciphertext, context::SEALContext, buffer::DenseVector{UInt8})
return load!(encrypted, context, buffer, length(buffer))
end

48 changes: 47 additions & 1 deletion src/encryptionparams.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ See also: [`SEALContext`](@ref)
mutable struct EncryptionParameters <: SEALObject
handle::Ptr{Cvoid}

function EncryptionParameters(scheme::SchemeType.SchemeTypeEnum)
function EncryptionParameters(scheme::SchemeType.SchemeTypeEnum=SchemeType.none)
handleref = Ref{Ptr{Cvoid}}(C_NULL)
retval = ccall((:EncParams_Create1, libsealc), Clong,
(UInt8, Ref{Ptr{Cvoid}}),
Expand Down Expand Up @@ -131,3 +131,49 @@ function parms_id(enc_param::EncryptionParameters)
return parms_id_
end

function save!(buffer::DenseVector{UInt8}, length::Integer,
compr_mode::ComprModeType.ComprModeTypeEnum, enc_param::EncryptionParameters)
out_bytes = Ref{Int64}(0)
retval = ccall((:EncParams_Save, libsealc), Clong,
(Ptr{Cvoid}, Ref{UInt8}, UInt64, UInt8, Ref{Int64}),
enc_param, buffer, length, compr_mode, out_bytes)
@check_return_value retval
return Int(out_bytes[])
end
function save!(buffer::DenseVector{UInt8}, length::Integer, enc_param::EncryptionParameters)
return save!(buffer, length, ComprModeType.default, enc_param)
end
function save!(buffer::DenseVector{UInt8}, enc_param::EncryptionParameters)
return save!(buffer, length(buffer), enc_param)
end

function save_size(compr_mode, enc_param::EncryptionParameters)
result = Ref{Int64}(0)
retval = ccall((:EncParams_SaveSize, libsealc), Clong,
(Ptr{Cvoid}, UInt8, Ref{Int64}),
enc_param, compr_mode, result)
@check_return_value retval
return Int(result[])
end
save_size(enc_param::EncryptionParameters) = save_size(ComprModeType.default, enc_param)

function load!(enc_param::EncryptionParameters, buffer::DenseVector{UInt8}, length)
in_bytes = Ref{Int64}(0)
retval = ccall((:EncParams_Load, libsealc), Clong,
(Ptr{Cvoid}, Ref{UInt8}, UInt64, Ref{Int64}),
enc_param, buffer, length, in_bytes)
@check_return_value retval
return Int(in_bytes[])
end
load!(enc_param::EncryptionParameters, buffer::DenseVector{UInt8}) = load!(enc_param, buffer,
length(buffer))

function Base.:(==)(enc_param1::EncryptionParameters, enc_param2::EncryptionParameters)
result = Ref{UInt8}(0)
retval = ccall((:EncParams_Equals, libsealc), Clong,
(Ptr{Cvoid}, Ptr{Cvoid}, Ref{UInt8}),
enc_param1, enc_param1, result)
@check_return_value retval
return Bool(result[])
end

16 changes: 16 additions & 0 deletions src/encryptor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,19 @@ function encrypt!(destination::Ciphertext, plain::Plaintext, encryptor::Encrypto
return destination
end

function encrypt_symmetric!(destination::Ciphertext, plain::Plaintext, encryptor::Encryptor)
retval = ccall((:Encryptor_EncryptSymmetric, libsealc), Clong,
(Ptr{Cvoid}, Ptr{Cvoid}, UInt8, Ptr{Cvoid}, Ptr{Cvoid}),
encryptor, plain, false, destination, C_NULL)
@check_return_value retval
return destination
end
function encrypt_symmetric(plain::Plaintext, encryptor::Encryptor)
destination = Ciphertext()
retval = ccall((:Encryptor_EncryptSymmetric, libsealc), Clong,
(Ptr{Cvoid}, Ptr{Cvoid}, UInt8, Ptr{Cvoid}, Ptr{Cvoid}),
encryptor, plain, true, destination, C_NULL)
@check_return_value retval
return destination
end

26 changes: 26 additions & 0 deletions src/plaintext.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,29 @@ function to_string(plain::Plaintext)
# Return as String but without terminating NULL byte
return String(message[1:end-1])
end

function save_size(compr_mode, plain::Plaintext)
result = Ref{Int64}(0)
retval = ccall((:Plaintext_SaveSize, libsealc), Clong,
(Ptr{Cvoid}, UInt8, Ref{Int64}),
plain, compr_mode, result)
@check_return_value retval
return Int(result[])
end
save_size(plain::Plaintext) = save_size(ComprModeType.default, plain)

function save!(buffer::DenseVector{UInt8}, length::Integer,
compr_mode::ComprModeType.ComprModeTypeEnum, plain::Plaintext)
out_bytes = Ref{Int64}(0)
retval = ccall((:Plaintext_Save, libsealc), Clong,
(Ptr{Cvoid}, Ref{UInt8}, UInt64, UInt8, Ref{Int64}),
plain, buffer, length, compr_mode, out_bytes)
@check_return_value retval
return Int(out_bytes[])
end
function save!(buffer::DenseVector{UInt8}, length::Integer, plain::Plaintext)
return save!(buffer, length, ComprModeType.default, plain)
end
function save!(buffer::DenseVector{UInt8}, plain::Plaintext)
return save!(buffer, length(buffer), plain)
end
Loading

0 comments on commit 70b87d2

Please sign in to comment.