Реализация Homomorphic Encryption для ML на зашифрованных данных
Homomorphic Encryption (HE) — шифрование, поддерживающее вычисления над зашифрованными данными без расшифровки. Клиент отправляет зашифрованные данные, сервер вычисляет inference и возвращает зашифрованный результат. Сервер в любой момент не имеет доступа к данным.
Типы гомоморфного шифрования
Частично гомоморфное (PHE) Поддерживает либо только сложение, либо только умножение над шифртекстами. Примеры: Paillier (только сложение), RSA (только умножение). Непригодны для ML — нейронные сети требуют оба типа операций.
Немного гомоморфное (SHE) Поддерживает ограниченное число произведений (глубина схемы). Шум накапливается при каждом умножении, при превышении порога — расшифровка даёт неверный результат. Применимо для неглубоких сетей.
Полностью гомоморфное (FHE) Поддерживает произвольные вычисления через операцию "bootstrapping" — периодическое "освежение" шифртекста. Вычислительно дорого, но применимо для сложных моделей.
CKKS (Cheon-Kim-Kim-Song) Специализированная схема для вычислений над действительными числами с приближёнными результатами. Идеальна для ML, где небольшая погрешность приемлема. Поддерживает SIMD-упаковку: один шифртекст содержит тысячи значений (батчевые вычисления).
Практическая реализация с Microsoft SEAL
import seal
from seal import EncryptionParameters, scheme_type, SEALContext
from seal import KeyGenerator, Encryptor, Evaluator, Decryptor
from seal import CKKSEncoder, RelinKeys, GaloisKeys
# Setup CKKS parameters
parms = EncryptionParameters(scheme_type.ckks)
poly_modulus_degree = 8192 # Security level
parms.set_poly_modulus_degree(poly_modulus_degree)
parms.set_coeff_modulus(seal.CoeffModulus.Create(poly_modulus_degree, [60, 40, 40, 60]))
context = SEALContext(parms)
keygen = KeyGenerator(context)
public_key = keygen.create_public_key()
secret_key = keygen.secret_key()
relin_keys = keygen.create_relin_keys()
galois_keys = keygen.create_galois_keys()
scale = 2.0**40
encoder = CKKSEncoder(context)
# Client encrypts input
input_data = [0.5, 0.3, 0.8, ...] # Feature vector
plain = encoder.encode(input_data, scale)
encrypted_input = Encryptor(context, public_key).encrypt(plain)
# Server computes on encrypted data (doesn't see actual values)
evaluator = Evaluator(context)
# ... matrix multiplication, activation approximation ...
encrypted_result = evaluator.multiply_plain(encrypted_input, weight_matrix)
# Client decrypts result
result = Decryptor(context, secret_key).decrypt(encrypted_result)
output = encoder.decode(result)
Аппроксимация нелинейных функций
Главная проблема HE для нейронных сетей: нелинейные функции (ReLU, sigmoid, tanh) не поддерживаются напрямую над шифртекстами — только полиномиальные операции.
Решение — полиномиальная аппроксимация:
- ReLU: аппроксимация полиномом степени 3–7 на рабочем диапазоне
- Sigmoid: ряд Тейлора или minimax polynomial
- Softmax: требует специальной обработки из-за деления
Точность аппроксимации vs. глубина полинома: степень 3 даёт ~1–2% деградации точности, но требует значительно меньше вычислений.
Альтернатива: замена архитектуры сети на HE-friendly — использование квадратичных активаций (x²) вместо ReLU.
Производительность и практические ограничения
| Операция | Plaintext | HE (CKKS) | Overhead |
|---|---|---|---|
| Линейный слой (1024→512) | 0.1ms | 80ms | ~800x |
| Batch inference (64 примера) | 5ms | 3000ms | ~600x |
| Простая CNN (MNIST) | 1ms | 30–60s | ~30000x |
Практически применимо сегодня:
- Логистическая регрессия и неглубокие нейронные сети
- Privacy-preserving inference (не обучение) для конкретных MLaaS-сценариев
- Финансовые расчёты с конфиденциальными параметрами
HE-as-a-Service паттерн
Наиболее реалистичный use case: облачный MLaaS провайдер хочет предлагать inference, не видя данных клиентов.
- Провайдер обучает модель на публичных/синтетических данных
- Клиент шифрует свои данные (FHE) на своей стороне
- Клиент отправляет шифртекст провайдеру
- Провайдер вычисляет inference на шифртексте
- Провайдер возвращает зашифрованный результат
- Клиент расшифровывает результат
Провайдер никогда не видит ни входные данные, ни результат. Медицинские данные, финансовые показатели, юридические документы — обрабатываются в облаке без раскрытия.
Библиотеки и фреймворки
- Microsoft SEAL: C++, Python bindings, поддержка BFV и CKKS
- HElib: IBM, C++, BGV схема
- OpenFHE: современная, поддерживает CKKS/BFV/CGGI
- Concrete (Zama): Python-friendly FHE компилятор, превращает PyTorch-модели в FHE-цепи
- TF-Encrypted: интеграция HE с TensorFlow
Срок реализации production-ready HE inference для небольшой модели: 8–16 недель с учётом подбора схемы, аппроксимации активаций и оптимизации производительности.







