Một dạng mã hóa cho phép tính toán trên bản mã tạo ra kết quả được mã hóa mà khi được giải mã sẽ khớp với kết quả của các thao tác như thể chúng đã được thực hiện trên bản rõ. — Massimo Bertaccini ( )
Sử dụng một đồng hình riêng tư đặc biệt để mã hóa dữ liệu của nó sao cho máy tính chia sẻ thời gian có thể hoạt động trên dữ liệu mà không cần phải giải mã trước.
Nói cách khác, tôi muốn xóa quá trình xử lý dữ liệu của mình mà không cấp quyền truy cập vào dữ liệu đó.
Nói cách khác, hàm(A, B) = hàm (A , B
) trong đó A and B
lần lượt là các giá trị được mã hóa của A và B. Điều này cho phép các bên thứ ba tính toán dữ liệu được mã hóa và cung cấp kết quả mà không cần biết về giá trị ban đầu. Với RSA, hai giá trị được mã hóa bằng cùng một khóa có thể được nhân lên và sản phẩm có thể được giải mã mang lại sản phẩm của các giá trị được mã hóa.
Thư viện | đề án | Ngôn ngữ | Giấy phép |
---|---|---|---|
BFV, BGV, CKKS | Trình bao bọc C++/C# | MIT | |
mở FHE | BFV, BGV, CKKS, DM, CGGI | C++ | Giấy phép 2 khoản BSD |
CKKS | C++ | Creative Commons 3.0 | |
TFHE (Hình xuyến) | rỉ sét | BSD-3-Khoản-Xóa | |
tfhe | rỉ sét | BSD-3-Khoản-Xóa | |
BFV, BGV, CKKS | Đi | Apache 2.0 | |
N/A – Sử dụng SEAL, PALISADE, HLib | Python, Docker | Apache 2.0 |
Để bắt đầu, một khóa công khai được tạo bởi máy khách và chia sẻ với máy chủ. Nó được sử dụng để mã hóa dữ liệu và cũng để thực hiện các phép tính số học trên dữ liệu được mã hóa. Cả máy khách và máy chủ đều sử dụng Bộ mã hóa. Máy khách tạo và giữ lại một khóa riêng được sử dụng để giải mã được sử dụng bởi Decryptor có tên thích hợp.
using Microsoft.Research.SEAL; protected SEALContext _context; private KeyGenerator _keyGenerator; private Encryptor _encryptor; private Decryptor _decryptor; protected IFitnessTrackerApiClient _apiClient; . . . _context = SEALUtils.GetContext(_config.Value.PolyModulusDegree, this.SchemeType); _keyGenerator = new KeyGenerator(_context); _keyGenerator.CreatePublicKey(out PublicKey publicKey); _keyGenerator.CreateRelinKeys(out RelinKeys relinKeys); _encryptor = new Encryptor(_context, _publicKey); _decryptor = new Decryptor(_context, _keyGenerator.SecretKey); . . . PublicKeyModelCKKS keyModelCKKS = new( SEALUtils.KeyToBase64String(_publicKey), SEALUtils.KeyToBase64String(relinKeys)); await _apiClient.SendPublicKeyCKKSAsync(keyModelCKKS);
Các khóa tái tuyến tính hóa được chuyển từ máy khách sang máy chủ. Theo Microsoft SEAL, chúng không có ý nghĩa ngữ nghĩa nào khác ngoài việc giảm kích thước của Bản mã sau thao tác nhân.
Tại dòng lệnh, người dùng nhập thời gian và khoảng cách.
Mỗi giá trị được mã hóa thành PlainText, sau đó được mã hóa thành Ciphertext và cuối cùng được mã hóa thành base64 trước khi gửi đến máy chủ.
using Microsoft.Research.SEAL; var plaintext = new Plaintext(); _encoder.Encode(value, _scale, plaintext); var ciphertext = new Ciphertext(); _encryptor.Encrypt(value, ciphertext); using (var ms = new MemoryStream()) { ciphertext.Save(ms); return Convert.ToBase64String(ms.ToArray()); }
RunItemCKKS metricsRequest = new( EncryptBase64(runItem.Distance), EncryptBase64(runItem.Time), EncryptBase64(1 / runItem.Time)); await _apiClient.AddNewRunningDistanceCKKSAsync(metricsRequest);
Máy chủ thực hiện chức năng khởi động tương tự tạo SEALContext chỉ sử dụng khóa chung và khóa tuyến tính hóa lại, sau đó xử lý yêu cầu:
var distance = SEALUtils.BuildCiphertextFromBase64String(request.Distance, _sealContext); var time = SEALUtils.BuildCiphertextFromBase64String(request.Time, _sealContext); var timeReciprocal = SEALUtils.BuildCiphertextFromBase64String(request.TimeReciprocal, _sealContext); Ciphertext speed = new(); _evaluator.Multiply(distance, timeReciprocal, speed); _evaluator.RelinearizeInplace(speed, _relinKeys); _runListCKKS.Add(new EncryptedRunInfoCKKS(distance, time, speed));
Nghịch đảo của thời gian được sử dụng để tính toán tốc độ cho lần chạy đã gửi và phương pháp RelinearizeInplace giảm kích thước của Bản mã kết quả . Khoảng cách, thời gian và tốc độ được lưu vào Danh sách trong bộ nhớ.
Phương thức GetMetrics tổng hợp danh sách và trả về:
public SummaryItemCKKS GetMetrics() { int count = _runListCKKS.Count; var totalDistanceCKKS = SumEncryptedValues(_runListCKKS.Select(m => m.Distance)); var totalTimeCKKS = SumEncryptedValues(_runListCKKS.Select(m => m.Time)); var totalSpeed = SumEncryptedValues(_runListCKKS.Select(m => m.Speed)); . . . protected Ciphertext SumEncryptedValues(IEnumerable<Ciphertext> encryptedData) { . . . Ciphertext encTotal = new(); _evaluator.AddMany(encryptedData, encTotal); return encTotal; . . . }
Vì máy chủ theo dõi số lần gửi lần chạy nên tổng số lần chạy không phải là giá trị được mã hóa. Giá trị không được mã hóa đó có thể được chuyển đổi thành Văn bản gốc và được sử dụng trong một thao tác được thực hiện trên Bản mã. Mặc dù đây là một ví dụ đơn giản, nhưng ý nghĩa rất đáng chú ý. Máy chủ có thể cung cấp các giá trị bổ sung được sử dụng trên dữ liệu được mã hóa, cho phép các nhà cung cấp bên thứ ba áp dụng dữ liệu độc quyền để tính toán đối với dữ liệu được mã hóa do khách hàng cung cấp.
Trong ví dụ bên dưới, tổng số đếm được chuyển đổi thành số nghịch đảo và được thêm vào Danh sách<double>. Hoạt động CKKS yêu cầu các giá trị danh sách được mã hóa, ngay cả khi danh sách chỉ chứa một giá trị. Vì vậy, List<double> được mã hóa thành PlainText . MultiplyPlainInplace nhân tổng Tốc độ với (1/số lần chạy) dẫn đến tốc độ trung bình. Để tiết kiệm không gian, kết quả được áp dụng cho TotalSpeed Ciphertext và các phím tuyến tính hóa lại làm giảm kích thước của đầu ra.
Plaintext encodedCountReciprocal = new(); List<double> averagePaceList = new(); double runCountReciprocal = 1 / (double)count; averagePaceList.Add(runCountReciprocal); _encoder.Encode(averagePaceList, _scale, encodedCountReciprocal); _evaluator.MultiplyPlainInplace(totalSpeed, encodedCountReciprocal); _evaluator.RelinearizeInplace(totalSpeed, _relinKeys);
Các giá trị được mã hóa, trả về và giải mã base64 trên máy khách. Máy khách thực hiện thêm bước chuyển đổi Bản rõ đã được giải mã thành Danh sách<double> .
var payload = Convert.FromBase64String(encryptedDistanceText); using var ms = new MemoryStream(payload); var ciphertext = new Ciphertext(); ciphertext.Load(_context, ms); var decryptedText = new Plaintext(); _decryptor.Decrypt(cypherText, decryptedText); List<double> distanceList = new(); _encoder.Decode(decryptedText, distanceList);
Dặm | Thời gian |
---|---|
2,5 | 0:35:32.643 |
2.2 | 0:32:48.826 |
2,8 | 0:34:52.036 |
Microsoft SEAL là một dự án Nghiên cứu của Microsoft và chưa sẵn sàng cho ứng dụng sản xuất. Tất cả các lớp triển khai tài nguyên không được quản lý và sử dụng IDisposable . Mã sản xuất sẽ cần bảo vệ chống rò rỉ bộ nhớ. Lớp SEALContext không tuân theo nguyên tắc trách nhiệm duy nhất. Nó bao gồm các phương thức cho cả BGV/BVF và CKKS. Hơn nữa, CKKS hỗ trợ các phép toán vectơ, nhưng không hỗ trợ phép cộng vectơ. Một Danh sách đơn lẻ<double> có thể được mã hóa thành một Văn bản mật mã duy nhất nhưng không có phương tiện nào để tính tổng các giá trị trong một Văn bản mật mã duy nhất . Nó có thể được thực hiện với , nhưng đó là một giải pháp dưới mức tối ưu.