Alors que le chiffrement homomorphe complet (FHE) a été initialement réalisé en 2009, il commence à recevoir plus d'attention maintenant que la puissance de calcul a rattrapé ses exigences de calcul ; cependant, l'objectif du cryptage homomorphe remonte à une décennie. Une recherche rapide en trouvera plusieurs définitions. C'est le plus direct et le plus succinct : Une forme de cryptage qui permet le calcul sur des textes chiffrés générant un résultat crypté qui, une fois décrypté, correspond au résultat des opérations comme si elles avaient été effectuées sur du texte en clair. — Massimo Bertaccini ( ) Algorithmes de cryptographie Considérez cette déclaration un instant. Le cryptage homomorphe permet d'effectuer des opérations sur des valeurs cryptées de sorte que les résultats décryptés produisent le résultat des opérations comme si elles étaient effectuées sur les valeurs non cryptées d'origine. La première mention que j'ai trouvée est (1978) dans laquelle les auteurs tentent d'empêcher les programmeurs système d'accéder aux données financières sensibles stockées dans un système sur site à l'aide d'un service de partage de temps à distance. On Data Banks and Privacy Homomorphisms Les données financières sensibles sont stockées dans la banque de données. Les services de temps partagé qui calculent les données n'implémentent pas une sécurité adéquate. Les programmeurs système ont accès aux données financières. Le papier précise : Utilisez un homomorphisme de confidentialité spécial pour crypter ses données afin que l'ordinateur en temps partagé puisse fonctionner sur les données sans qu'il soit nécessaire de les décrypter au préalable. En d'autres termes, je souhaite supprimer le de mes données sans en céder l' . traitement accès Pour le dire autrement encore, function(A, B) = function (A ) où A sont des valeurs chiffrées de A et B, respectivement. Cela permet à des tiers de calculer des données cryptées et de fournir les résultats sans avoir aucune connaissance de la valeur d'origine. Avec RSA, deux valeurs chiffrées avec la même clé peuvent être multipliées et le produit peut être déchiffré pour donner le produit des valeurs chiffrées. , B &nbsp;and B Obtenez 5_6 à l'aide de RSA(5)_ RSA(6) : RSA(5) = (5^17) mod 3233 = 3096 RSA(6) = (6^17) mod 3233 = 824 3096*824 = 254864 RSA^-1(254864) = 254864^2753 (mod 3233) = 30 5*6 = 30 Cependant, cela ne fonctionne pas pour l'addition. RSA est un schéma de chiffrement partiellement homomorphe (PHE) en ce sens qu'il ne prend en charge que la multiplication. La chronologie ci-dessous montre la progression des schémas (PHE) jusqu'au chiffrement quelque peu homomorphe (SHWE) qui permet des combinaisons limitées d'addition et de multiplication. Ces opérations pouvaient être répétées jusqu'à cinq fois avant d'aboutir à un résultat invalide. Puis vint le premier schéma FHE de qui permettait des additions et des multiplications répétées sans perte de fidélité. Craig Gentry Bibliothèques de chiffrement homomorphe Depuis 2009, les programmes FHE et les bibliothèques se sont multipliés. Une bibliothèque Régimes Langue Licence SCEAU Microsoft BFV, BGV, CKKS Wrapper C++/C# MIT Ouvrir FHE BFV, BGV, CKKS, DM, CGGI C++ Licence BSD à 2 clauses HEAN CKKS C++ Creative Commons 3.0 TFHE TFHE (Tore) Rouiller BSD-3-Clause-Effacer Béton TFHE Rouiller BSD-3-Clause-Effacer Lattigo BFV, BGV, CKKS Va Apache 2.0 Boîte à outils Intel Homomorphic Encryption N/A – Utilise SEAL, PALISADE, HLib Python, Docker Apache 2.0 Microsoft SEAL (Simple Encrypted Arithmetic Library) est développé en C++ 17 avec un wrapper C#. Sorti à l'origine en 2015, il est toujours en cours de développement. Le comprend qui devraient être explorés si vous souhaitez approfondir. dépôt github des exemples C# approfondis Ces schémas sont pris en charge par SEAL et incluent des opérations homomorphes pour l'addition, la division, la soustraction et l'exponentiation, mais pas la division. Brakerski-Gentry-Vaikuntanathan (BGV)/Fan-Vercauteren (BFV) Nombres entiers (longs) À utiliser si la précision est une exigence Le calcul est plus lent que CKKS Les valeurs chiffrées avec BGV peuvent être utilisées avec des valeurs chiffrées avec BFV Les valeurs chiffrées avec BGV/BVF ne peuvent pas être utilisées avec des valeurs chiffrées avec CKKS Revisiter les schémas de chiffrement homomorphes pour les champs finis Cheon-Kim-Kim-Song (CKKS) Virgule flottante (double) À utiliser si la précision n'est pas requise Les valeurs chiffrées avec CKKS ne peuvent pas être utilisées avec des valeurs chiffrées avec BGV/BFV Le calcul est plus rapide que BFV/BGF Chiffrement et calcul avec Microsoft SEAL Ces exemples utilisent le package Nuget et le schéma CKKS. Les trackers de santé, comme FitBit et AppleHeath, nécessitent de renoncer à une certaine confidentialité. Ils collectent des informations personnelles telles que le nombre de pas et les coordonnées géographiques des mouvements du porteur, la fréquence des battements cardiaques et d'autres statistiques vitales. Avec un cryptage homomorphe, ces agrégateurs de mesures de santé peuvent toujours fonctionner sur nos données sans avoir accès aux données brutes. Microsoft.Research.SEALNet Dans cet exemple simple, le client envoie des métriques d'exécution, y compris la distance et le temps. Le serveur agrège les données cryptées et calcule la vitesse moyenne. Pour commencer, une clé publique est créée par le client et partagée avec le serveur. Il est utilisé pour chiffrer des données et également pour effectuer des opérations arithmétiques sur des données chiffrées. Le client et le serveur utilisent tous deux un Le client génère et conserve une clé privée utilisée pour le déchiffrement utilisé par le bien nommé . Encryptor. Decryptor Une partie malveillante qui intercepte les données pourrait utiliser la clé publique sur les données cryptées et la renvoyer à l'appelant en usurpant le serveur. Le serveur doit signer le résultat et le client doit vérifier la signature pour s'assurer qu'elle est renvoyée par une partie de confiance. 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); Les clés de relinéarisation sont transmises du client au serveur. Selon Microsoft SEAL, ils n'ont aucune signification sémantique autre que de réduire la taille du suite à une opération de multiplication. Ciphertext Sur la ligne de commande, l'utilisateur entre le temps et la distance. Chaque valeur est encodée en puis chiffrée en et enfin encodée en base64 avant de l'envoyer au serveur. PlainText, Ciphertext 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()); } Étant donné que les schémas de chiffrement homomorphes ne prennent pas en charge la division (CKKS ne fait pas exception), le client doit aider le serveur. La formule de la vitesse est : distance/temps Une autre façon de l'écrire est, distance * (1/temps) Ainsi, le client envoie : RunItemCKKS metricsRequest = new( EncryptBase64(runItem.Distance), EncryptBase64(runItem.Time), EncryptBase64(1 / runItem.Time)); await _apiClient.AddNewRunningDistanceCKKSAsync(metricsRequest); Le serveur exécute une fonction d'amorçage similaire en créant un en utilisant uniquement la clé publique et les clés de relinéarisation, puis traite la requête : 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)); L'inverse du temps est utilisé pour calculer la vitesse de l'exécution soumise et la méthode réduit la taille du texte chiffré résultant La distance, le temps et la vitesse sont enregistrés dans une RelinearizeInplace . liste en mémoire. La méthode agrège la liste et renvoie : GetMetrics nombre total de courses distance totale temps total vitesse moyenne 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; . . . } Pour obtenir la vitesse moyenne, l'inverse du décompte est utilisé, donc plutôt que d'utiliser : (somme de la vitesse)/nombre ou runs que nous utilisons : (somme de la vitesse) * (1/nombre de courses) Étant donné que le serveur conserve une trace du nombre de soumissions d'exécutions, le nombre total d'exécutions n'est pas une valeur chiffrée. Cette valeur non chiffrée peut être convertie en et utilisée dans une opération effectuée sur le Bien qu'il s'agisse d'un exemple simple, les implications méritent d'être notées. Le serveur peut fournir des valeurs supplémentaires utilisées sur les données cryptées permettant aux fournisseurs tiers d'appliquer des données exclusives aux calculs par rapport aux données cryptées fournies par le client. texte brut texte chiffré. Dans l'exemple ci-dessous, le nombre total est converti en réciproque et ajouté à une Les opérations CKKS attendent des valeurs de liste chiffrées, même si la liste ne contient qu'une seule valeur. Ainsi, le est encodé en un . multiplie totalSpeed par (1/nombre d'exécutions), ce qui donne la vitesse moyenne. Pour économiser de l'espace, le résultat est appliqué au texte chiffré et les clés de relinéarisation réduisent la taille de la sortie. List<double>. List<double> PlainText MultiplyPlainInplace 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); Les valeurs sont encodées en base64, renvoyées et déchiffrées sur le client. Le client prend l'étape supplémentaire de convertir le texte déchiffré en . brut 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); L'envoi des valeurs suivantes donne les totaux et le rythme moyen calculés par un service qui totalise le total et la moyenne sans déchiffrer les données envoyées par le client. Milles Temps 2.5 0:35:32.643 2.2 0:32:48.826 2.8 0:34:52.036 Le serveur calcule les données et renvoie le nombre total de courses, la distance, le temps et le rythme sans décrypter aucune des données envoyées. Résumé Microsoft SEAL est un projet Microsoft Research et n'est pas prêt pour une application de production. Toutes les classes implémentent et utilisent des ressources non managées. Le code de production devrait se protéger contre une fuite de mémoire. La classe ne respecte pas le principe de responsabilité unique. Il comprend des méthodes pour BGV/BVF et CKKS. De plus, CKKS prend en charge les opérations vectorielles, mais pas l'addition de vecteurs. Une seule peut être chiffrée en un seul mais il n'y a aucun moyen de sommer les valeurs dans un seul Cela peut être fait avec , mais c'est une solution sous-optimale. IDisposable SEALContext List<double> CipherText CipherText. la rotation vectorielle Cet exemple de code Fitness Tracker est une introduction simple à un sujet complexe. Il existe un certain nombre de cas d'utilisation convaincants avec une logique plus complexe : Détection de marqueurs génétiques Protection du modèle biométrique Un suivi humain sécurisé pour vieillir chez soi Détection de fraude à la carte de crédit Le chiffrement homomorphe a été largement utilisé dans le milieu universitaire et dans les prototypes. Les applications pratiques ont été limitées par la puissance de calcul requise par les schémas de chiffrement homomorphe. L'accélération GPU et les processeurs ASIC continueront d'éroder cette barrière. Intel développe l' , spécialement conçu pour les schémas de chiffrement homomorphe, en collaboration avec Microsoft et DARPA. Le NASDAQ finance également avec apprentissage automatique pour la détection des fraudes. La communauté FHE.org est une excellente ressource pour les développements les plus récents dans cet espace. Il a un actif. accélérateur matériel FHE un projet de R&D utilisant le chiffrement homomorphe serveur Discord Tous les exemples de code de cet article sont disponibles sur . Pour un exemple Microsoft SEAL plus approfondi, consultez ces . johniwasz/microsoft-seal-samples exemples .NET Également publié ici.