Facebook
From ADNAN ALI, 7 Months ago, written in SAS.
Embed
Download Paste or View Raw
Hits: 391
  1. // SPDX-License-Identifier: GPL-3.0
  2. pragma solidity >=0.8.2 <0.9.0;
  3.  
  4. contract PaillierHomomorphicEncryption {
  5.     uint256 public p;
  6.     uint256 public q;
  7.     uint256 public n;
  8.     uint256 public g;
  9.     uint256 public l;
  10.     uint256 public m;
  11.  
  12.     struct PrivateKey {
  13.         uint256 l;
  14.         uint256 m;
  15.     }
  16.  
  17.     struct PublicKey {
  18.         uint256 n;
  19.         uint256 n_sq;
  20.         uint256 g;
  21.     }
  22.  
  23.     PublicKey publicKey;
  24.     PrivateKey privateKey;
  25.  
  26.     constructor() {
  27.         // Initialize key generation parameters (simplified)
  28.         p = 1000000009; // Replace with a prime number
  29.         q = 1000000007; // Replace with another prime number
  30.         n = p * q;
  31.         l = (p - 1) * (q - 1);
  32.         m = modInverse(l, n, 1000000); // Calculate the modular inverse
  33.  
  34.         publicKey = PublicKey(n, n * n, n+1);
  35.         privateKey = PrivateKey(l, m);
  36.     }
  37.  
  38.     function modInverse(uint256 a, uint256 pp, uint256 maxiter) public pure returns (uint256) {
  39.         uint256 r = a;
  40.         uint256 d = 1;
  41.         for (uint256 i = 0; i < min(pp, maxiter); i++) {
  42.             d = ((pp / r + 1) * d) % pp;
  43.             r = (d * a) % pp;
  44.             if (r == 1) {
  45.                 break;
  46.             }
  47.         }
  48.         return d;
  49.     }
  50.  
  51.     function min(uint256 a, uint256 b) internal pure returns (uint256) {
  52.         return a < b ? a : b;
  53.     }
  54.  
  55.     // Encrypt a plaintext value
  56.     function encrypt(uint256 plaintext) public view returns (uint256) {
  57.         require(plaintext < n, "Plaintext must be smaller than n");
  58.         uint256 r = 5;
  59.         uint256 x = powmod(r, publicKey.n, publicKey.n_sq);
  60.         return (powmod(publicKey.g, plaintext, publicKey.n_sq) * x) % publicKey.n_sq;
  61.  
  62.     }
  63.  
  64.     // Decrypt a ciphertext value
  65.     function decrypt(uint256 ciphertext) public view returns (uint256) {
  66.         uint256 c1 = (powmod(ciphertext, privateKey.l, publicKey.n_sq) - 1) % publicKey.n_sq;
  67.         uint256 plaintext = ((c1 / publicKey.n) * privateKey.m) % publicKey.n;
  68.        
  69.         return plaintext;
  70.     }
  71.  
  72.     function add(uint256 a, uint256 b) public view returns (uint256) {
  73.         uint256 a_enc = encrypt(a);
  74.         uint256 b_enc = encrypt(b);
  75.         uint256 product_enc = (a_enc * b_enc) % publicKey.n_sq;
  76.         return decrypt(product_enc);
  77.     }
  78.  
  79.  
  80.     function powmod(uint256 a, uint256 b, uint256 n) public pure returns (uint256) {
  81.         if(a > n)
  82.             a-=n;
  83.         if (b == 0) {
  84.             return 1;
  85.         } else if (b % 2 == 0) {
  86.             uint256 temp = powmod(a, b / 2, n);
  87.             return (temp * temp) % n;
  88.         } else {
  89.             uint256 temp = powmod(a, (b - 1) / 2, n);
  90.             return (a * ((temp * temp) % n)) % n;
  91.         }
  92.     }
  93. }