• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hpsc-lab / SecureArithmetic.jl / 13038842056

29 Jan 2025 07:22PM UTC coverage: 96.603%. First build
13038842056

Pull #59

github

web-flow
Merge ad526c4f0 into daf7aabfa
Pull Request #59: Add Secure Array

489 of 531 new or added lines in 6 files covered. (92.09%)

654 of 677 relevant lines covered (96.6%)

158.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.51
/src/unencrypted.jl
1
"""
2
    Unencrypted
3

4
An alternative backend to use instead of [`OpenFHEBackend`](@ref) to experiment with
5
algorithms on unencrypted data.
6

7
See also: [`SecureContext`](@ref), [`OpenFHEBackend`](@ref)
8
"""
9
struct Unencrypted <: AbstractCryptoBackend
30✔
10
    # No data fields required
11
end
12

13
"""
14
    generate_keys(context::SecureContext{<:Unencrypted})
15

16
Return public and private keys for use with unencrypted data.
17

18
See also: [`PublicKey`](@ref), [`PrivateKey`](@ref), [`SecureContext`](@ref),
19
[`Unencrypted`](@ref)
20
"""
21
function generate_keys(context::SecureContext{<:Unencrypted})
36✔
22
    PublicKey(context, nothing), PrivateKey(context, nothing)
36✔
23
end
24

25
"""
26
    init_multiplication!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey)
27

28
An empty duplicate of [`init_multiplication!`](@ref) for unencrypted data.
29

30
See also: [`SecureContext`](@ref), [`Unencrypted`](@ref), [`PrivateKey`](@ref),
31
[`init_multiplication!`](@ref)
32
"""
33
init_multiplication!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey) = nothing
30✔
34

35
"""
36
    init_rotation!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey, shifts)
37

38
An empty duplicate of [`init_rotation!`](@ref) for unencrypted data.
39

40
See also: [`SecureContext`](@ref), [`Unencrypted`](@ref), [`PrivateKey`](@ref),
41
[`init_rotation!`](@ref)
42
"""
43
init_rotation!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey, shifts) = nothing
12✔
44

45
"""
46
    init_matrix_rotation!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey,
47
                          shifts, shape)
48

49
An empty duplicate of [`init_matrix_rotation!`](@ref) for unencrypted data.
50

51
See also: [`SecureContext`](@ref), [`Unencrypted`](@ref), [`PrivateKey`](@ref),
52
[`init_matrix_rotation!`](@ref)
53
"""
54
init_matrix_rotation!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey,
18✔
55
                      shifts, shape) = nothing
56

57
"""
58
    init_array_rotation!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey,
59
                         shifts, shape)
60

61
An empty duplicate of [`init_array_rotation!`](@ref) for unencrypted data.
62

63
See also: [`SecureContext`](@ref), [`Unencrypted`](@ref), [`PrivateKey`](@ref),
64
[`init_array_rotation!`](@ref)
65
"""
66
init_array_rotation!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey,
42✔
67
                     shifts, shape) = nothing
68

69
"""
70
    init_bootstrapping!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey)
71
              
72

73
An empty duplicate of [`init_bootstrapping!`](@ref) for unencrypted data.
74

75
See also: [`SecureContext`](@ref), [`Unencrypted`](@ref), [`PrivateKey`](@ref),
76
[`init_bootstrapping!`](@ref)
77
"""
78
init_bootstrapping!(context::SecureContext{<:Unencrypted}, private_key::PrivateKey) = nothing
18✔
79

80
"""
81
    PlainVector(data::Vector{<:Real}, context::SecureContext{<:Unencrypted})
82

83
Constructor for data type [`PlainVector`](@ref) takes an unencrypted `data` vector and a `context`
84
object of type `SecureContext{<:Unencrypted}`. Returns [`PlainVector`](@ref) with not encoded and
85
not encrypted data. The context can be utilized later for encryption using [`encrypt`](@ref),
86
resulting in [`SecureVector`](@ref).
87
        
88
See also: [`PlainVector`](@ref), [`SecureVector`](@ref), [`encrypt`](@ref), [`decrypt`](@ref)
89
"""
90
function PlainVector(data::Vector{<:Real}, context::SecureContext{<:Unencrypted})
42✔
91
    PlainArray(data, context)
42✔
92
end
93

94
"""
95
    PlainMatrix(data::Matrix{<:Real}, context::SecureContext{<:Unencrypted})
96

97
Constructor for data type [`PlainMatrix`](@ref) takes an unencrypted `data` matrix and a `context`
98
object of type `SecureContext{<:Unencrypted}`. Returns [`PlainMatrix`](@ref) with not encoded and
99
not encrypted data. The context can be utilized later for encryption using [`encrypt`](@ref),
100
resulting in [`SecureMatrix`](@ref).
101
        
102
See also: [`PlainMatrix`](@ref), [`SecureMatrix`](@ref), [`encrypt`](@ref), [`decrypt`](@ref)
103
"""
104
function PlainMatrix(data::Matrix{<:Real}, context::SecureContext{<:Unencrypted})
30✔
105
    PlainArray(data, context)
30✔
106
end
107

108
"""
109
    PlainArray(data::Array{<:Real}, context::SecureContext{<:Unencrypted})
110

111
Constructor for data type [`PlainArray`](@ref) takes an unencrypted `data` array and a `context`
112
object of type `SecureContext{<:Unencrypted}`. Returns [`PlainArray`](@ref) with not encoded and
113
not encrypted data. The context can be utilized later for encryption using [`encrypt`](@ref),
114
resulting in [`SecureArray`](@ref).
115
        
116
See also: [`PlainArray`](@ref), [`SecureArray`](@ref), [`encrypt`](@ref), [`decrypt`](@ref)
117
"""
118
function PlainArray(data::Array{<:Real}, context::SecureContext{<:Unencrypted})
126✔
119
    PlainArray(data, size(data), length(data), context)
126✔
120
end
121

122
function PlainArray(data::Vector{<:Real}, context::SecureContext{<:Unencrypted},
12✔
123
                    shape::Tuple)
124
    reshaped_data = Array(reshape(data, shape))
18✔
125
    PlainArray(reshaped_data, context)
12✔
126
end
127

128
function Base.show(io::IO, pa::PlainArray{<:Unencrypted})
204✔
129
    print(io, pa.data)
204✔
130
end
131

132
function Base.show(io::IO, ::MIME"text/plain", pa::PlainArray{<:Unencrypted})
18✔
133
    print(io, pa.shape, "-shaped PlainArray{Unencrypted}:\n")
18✔
134
    Base.print_matrix(io, pa.data)
18✔
135
end
136

137
"""
138
    collect(pa::PlainArray{<:Unencrypted})
139

140
Return the real-valued data contained in `pa`.
141

142
See also: [`PlainArray`](@ref)
143
"""
144
function Base.collect(pa::PlainArray{<:Unencrypted})
132✔
145
    pa.data
132✔
146
end
147

148
"""
149
    level(a::Union{SecureArray{<:Unencrypted}, PlainArray{<:Unencrypted}})
150

151
Return the number of scalings, referred to as the level, performed over `a`. For data type derived
152
from `Unencrypted`, the level is always equal to 0.
153

154
See also: [`PlainArray`](@ref), [`SecureArray`](@ref)
155
"""
156
function level(a::Union{SecureArray{<:Unencrypted}, PlainArray{<:Unencrypted}})
18✔
157
    0
×
158
end
159

160
function encrypt_impl(data::Array{<:Real}, public_key::PublicKey,
18✔
161
                      context::SecureContext{<:Unencrypted})
162
    SecureArray(data, size(data), length(data), context)
18✔
163
end
164

165
function encrypt_impl(plain_array::PlainArray{<:Unencrypted}, public_key::PublicKey)
108✔
166
    SecureArray(plain_array.data, size(plain_array), capacity(plain_array),
108✔
167
                plain_array.context)
168
end
169

170
function decrypt_impl!(plain_array::PlainArray{<:Unencrypted},
258✔
171
                       secure_array::SecureArray{<:Unencrypted}, private_key::PrivateKey)
172
    plain_array.data .= secure_array.data
387✔
173

NEW
174
    plain_array
129✔
175
end
176

177
function decrypt_impl(secure_array::SecureArray{<:Unencrypted}, private_key::PrivateKey)
258✔
178
    plain_array = PlainArray(similar(secure_array.data), size(secure_array), capacity(secure_array),
387✔
179
                             secure_array.context)
180

181
    decrypt!(plain_array, secure_array, private_key)
258✔
182
end
183

184
"""
185
    bootstrap!(secure_array::SecureArray{<:Unencrypted}, num_iterations = 1,
186
               precision = 0)
187
     
188
An empty duplicate of [`bootstrap!`](@ref) for unencrypted data.
189

190
See also: [`SecureArray`](@ref), [`Unencrypted`](@ref), [`bootstrap!`](@ref),
191
[`init_bootstrapping!`](@ref)
192
"""
193
bootstrap!(secure_array::SecureArray{<:Unencrypted}, num_iterations = 1,
36✔
194
           precision = 0) = secure_array
195

196

197
############################################################################################
198
# Arithmetic operations
199
############################################################################################
200

201
function add(sa1::SecureArray{<:Unencrypted}, sa2::SecureArray{<:Unencrypted})
36✔
202
    SecureArray(sa1.data .+ sa2.data, size(sa1), capacity(sa1), sa1.context)
36✔
203
end
204

205
function add(sa::SecureArray{<:Unencrypted}, pa::PlainArray{<:Unencrypted})
36✔
206
    SecureArray(sa.data .+ pa.data, size(sa), capacity(sa), sa.context)
36✔
207
end
208

209
function add(sa::SecureArray{<:Unencrypted}, scalar::Real)
36✔
210
    SecureArray(sa.data .+ scalar, size(sa), capacity(sa), sa.context)
36✔
211
end
212

213
function subtract(sa1::SecureArray{<:Unencrypted}, sa2::SecureArray{<:Unencrypted})
36✔
214
    SecureArray(sa1.data .- sa2.data, size(sa1), capacity(sa1), sa1.context)
36✔
215
end
216

217
function subtract(sa::SecureArray{<:Unencrypted}, pa::PlainArray{<:Unencrypted})
18✔
218
    SecureArray(sa.data .- pa.data, size(sa), capacity(sa), sa.context)
18✔
219
end
220

221
function subtract(pa::PlainArray{<:Unencrypted}, sa::SecureArray{<:Unencrypted})
18✔
222
    SecureArray(pa.data .- sa.data, size(sa), capacity(sa), sa.context)
18✔
223
end
224

225
function subtract(sa::SecureArray{<:Unencrypted}, scalar::Real)
18✔
226
    SecureArray(sa.data .- scalar, size(sa), capacity(sa), sa.context)
18✔
227
end
228

229
function subtract(scalar::Real, sa::SecureArray{<:Unencrypted})
18✔
230
    SecureArray(scalar .- sa.data, size(sa), capacity(sa), sa.context)
18✔
231
end
232

233
function negate(sa::SecureArray{<:Unencrypted})
18✔
234
    SecureArray(-sa.data, size(sa), capacity(sa), sa.context)
18✔
235
end
236

237
function multiply(sa1::SecureArray{<:Unencrypted}, sa2::SecureArray{<:Unencrypted})
36✔
238
    SecureArray(sa1.data .* sa2.data, size(sa1), capacity(sa1), sa1.context)
36✔
239
end
240

241
function multiply(sa::SecureArray{<:Unencrypted}, pa::PlainArray{<:Unencrypted})
36✔
242
    SecureArray(sa.data .* pa.data, size(sa), capacity(sa), sa.context)
36✔
243
end
244

245
function multiply(sa::SecureArray{<:Unencrypted}, scalar::Real)
54✔
246
    SecureArray(sa.data .* scalar, size(sa), capacity(sa), sa.context)
54✔
247
end
248

249
function rotate(sa::SecureArray{<:Unencrypted, 1}, shift; wrap_by)
216✔
250
    # `wrap_by` can be ignored since here length is always equal to capacity
251
    rotate(sa, shift[1])
162✔
252
end
253

254
# The function is required to avoid infinite recursion in the first rotate method with
255
# the `wrap_by` keyword argument.
256
function rotate(sa::SecureArray{<:Unencrypted, 1}, shift::Integer)
108✔
257
    SecureArray(circshift(sa.data, shift), size(sa), capacity(sa), sa.context)
162✔
258
end
259

260
function rotate(sa::SecureArray{<:Unencrypted, N}, shift) where N
66✔
261
    SecureArray(circshift(sa.data, shift), size(sa), capacity(sa), sa.context)
66✔
262
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc