密令化された結果を生产する密令文の計算を概率にする密令化の主要形式。復号化すると、平文で実行されたかのように方法の結果と相一致します。 — Massimo Bertaccini ( )
特別なプライバシー準同型を使用してデータを暗号化し、タイムシェア コンピュータが最初にデータを復号化する必要なくデータを操作できるようにします。
別の言い方をすれば、データへのアクセスを与えることなく、データの処理を削除したいと考えています。
さらに別の言い方をすれば、 function(A, B) = function (A , B
) ここで、 A and B
は、それぞれ A と B の暗号化された値です。これにより、第三者は暗号化されたデータを計算し、元の値を知らなくても結果を提供できます。 RSA を使用すると、同じキーで暗号化された 2 つの値を乗算し、積を復号化して、暗号化された値の積を得ることができます。
図書館 | スキーム | 言語 | ライセンス |
---|---|---|---|
BFV、BGV、CKKS | C++/C# ラッパー | MIT | |
FHEを開く | BFV、BGV、CKKS、DM、CGGI | C++ | BSD 2 条項ライセンス |
CKKS | C++ | クリエイティブ・コモンズ 3.0 | |
TFHE (トーラス) | さび | BSD-3-Clause-Clear | |
TFHE | さび | BSD-3-Clause-Clear | |
BFV、BGV、CKKS | 行け | アパッチ 2.0 | |
該当なし – SEAL、PALISADE、HLib を动用 | パイソン、ドッカー | アパッチ 2.0 |
開始するには、公開鍵がクライアントによって作成され、サーバーと共有されます。データを暗号化したり、暗号化されたデータに対して算術演算を実行したりするために使用されます。クライアントとサーバーの両方がEncryptor を使用します。クライアントは、適切な名前のDecryptorによって使用される復号化に使用される秘密鍵を生成して保持します。
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);
再線形化キーは、クライアントからサーバーに渡されます。 Microsoft SEAL によると、これらには、乗算操作に続く暗号文のサイズを縮小する以外に意味的な意味はありません。
コマンド ラインで、ユーザーは時間と距離を入力します。
各値は PlainText にエンコードされ、次に Ciphertext に暗号化され、最後に base64 にエンコードされてからサーバーに送信されます。
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);
サーバーは、公開鍵と再線形化鍵のみを使用してSEALContextを作成する同様のブートストラップ機能を実行し、要求を処理します。
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));
送信された実行の速度を計算するために時間の逆数が使用され、 RelinearizeInplaceメソッドが結果の暗号文のサイズを縮小します。距離、時間、速度はメモリ内のリストに保存されます。
GetMetricsメソッドは、リストを集計して次を返します。
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; . . . }
サーバーは実行の送信数を追跡しているため、実行の合計数は暗号化された値ではありません。その暗号化されていない値を平文に変換し、暗号文で実行される操作で使用できます。これは単純な例ですが、その影響は注目に値します。サーバーは、暗号化されたデータで使用される追加の値を提供できるため、サードパーティのプロバイダーは、顧客が提供した暗号化されたデータに対する計算に独自のデータを適用できます。
以下の例では、合計カウントが逆数に変換され、 List<double> に追加されます。 CKKS 操作は、リストに単一の値しか含まれていない場合でも、暗号化されたリスト値を想定しています。したがって、 List<double>はPlainTextにエンコードされます。 MultiplyPlainInplaceは、totalSpeed に (1/実行回数) を掛けて、平均速度を求めます。スペースを節約するために、結果はtotalSpeed 暗号文に適用され、再線形化キーによって出力のサイズが縮小されます。
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);
値は base64 でエンコードされて返され、クライアントで復号化されます。クライアントは、復号化されたプレーンテキストをList<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);
マイル | 時間 |
---|---|
2.5 | 0:35:32.643 |
2.2 | 0:32:48.826 |
2.8 | 0:34:52.036 |
Microsoft SEAL は Microsoft Research プロジェクトであり、実稼働アプリケーションの準備ができていません。すべてのクラスはIDisposableを実装し、アンマネージ リソースを使用します。プロダクション コードは、メモリ リークから保護する必要があります。 SEALContextクラスは、単一責任の原則に従っていません。 BGV/BVF と CKKS の両方のメソッドが含まれています。さらに、CKKS はベクトル操作をサポートしますが、ベクトル加算はサポートしません。単一のList<double>を単一のCipherText に暗号化できますが、単一の CipherTextの値を合計する手段はありません。 で行うことができますが、それは次善の解決策です。