The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
The secure-inference vignette evaluated a linear model
on encrypted patient data. Here the prediction also needs the logistic
sigmoid
\[\sigma(\eta) = \frac{1}{1 + e^{-\eta}}.\]
The sigmoid is not a polynomial, and BFV/BGV and CKKS support only addition and multiplication. We replace it with a Chebyshev polynomial approximation, so the whole prediction (linear predictor and sigmoid) is computed on encrypted values.
A hospital holds patient data. A researcher holds a trained
logistic-regression model. The researcher wants to score patients
without seeing their data; the hospital wants predictions without seeing
the model coefficients. This is the two-party setting of
secure-inference with a nonlinear model.
set.seed(123)
n <- 500
age <- rnorm(n, 55, 10)
biomarker <- rnorm(n, 0, 1)
prob <- plogis(-2 + 0.03 * age + 0.8 * biomarker)
outcome <- rbinom(n, 1, prob)
model <- glm(outcome ~ age + biomarker, family = binomial)
beta <- coef(model)
cat("Coefficients (intercept, age, biomarker):", round(beta, 4), "\n")
## Coefficients (intercept, age, biomarker): -2.2671 0.0348 0.8991
The Chebyshev polynomial needs enough multiplicative depth. We use
depth 8 and enable Feature$ADVANCEDSHE, which provides the
polynomial-evaluation functions.
library(openfhe.R)
cc <- fhe_context("CKKS",
multiplicative_depth = 8L,
scaling_mod_size = 50L,
batch_size = 16L,
features = c(Feature$ADVANCEDSHE))
keys <- key_gen(cc, eval_mult = TRUE)
new_age <- c(45, 52, 60, 38, 70, 55, 48, 63,
41, 57, 66, 44, 72, 50, 59, 35)
new_bm <- c(-0.5, 0.3, 1.2, -1.0, 0.8, 0.1, -0.3, 1.5,
-0.8, 0.6, 0.9, -0.4, 1.1, 0.0, 0.7, -1.2)
ct_age <- encrypt(keys@public, make_ckks_packed_plaintext(cc, new_age), cc = cc)
ct_bm <- encrypt(keys@public, make_ckks_packed_plaintext(cc, new_bm), cc = cc)
\(\eta = \beta_0 + \beta_1\, \text{age} + \beta_2\, \text{biomarker}\), all arithmetic on encrypted data:
ct_eta <- ct_age * beta[2]
ct_eta <- ct_eta + ct_bm * beta[3]
ct_eta <- ct_eta + beta[1]
openfhe.R exposes Chebyshev approximations of common
transcendental functions, including the logistic sigmoid. The interval
\([a, b]\) must cover the range of
\(\eta\) for these patients. A
degree-16 approximation fits within the depth set above; its error is
measured in Step 5.
ct_prob <- eval_logistic(ct_eta, a = -4, b = 4, degree = 16)
result <- decrypt(ct_prob, keys@secret, cc = cc)
set_length(result, 16L)
encrypted_probs <- get_real_packed_value(result)[1:16]
cleartext_probs <- plogis(beta[1] + beta[2] * new_age + beta[3] * new_bm)
max_err <- max(abs(encrypted_probs - cleartext_probs))
cat(sprintf("Max absolute error vs cleartext sigmoid: %.2e\n", max_err))
## Max absolute error vs cleartext sigmoid: 5.79e-06
secure-inference; see
the threat-model caveat below.vignette("secure-inference") applies here. The hospital
holds the secret key and could recover the coefficients from predictions
on chosen inputs. The sigmoid makes this harder than in the linear case
but does not prevent it. A deployment would need further protection,
such as output differential privacy, query limits, or threshold
FHE.These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.