11"""
2- Paillier cryptosystem was introduced in 1999 by Pascal Paillier. It is
2+ Paillier cryptosystem was introduced in 1999 by Pascal Paillier. It is
33an asymmetric algorithm for public key cryptography.
44 ----Public-Key Cryptosystems Based on Composite Degree Residuosity Classes
55 ----https://link.springer.com/content/pdf/10.1007/3-540-48910-X_16.pdf
5252# homomorphicADD() ++
5353# homomorphicMUL() ++
5454
55-
56-
5755import sympy
5856import random
5957
58+
6059class Utils :
6160 def primeGenerator (bit_size ):
6261 """
6362 Uses sympy.randprime() for genearing a prime number
6463 of a particular bit-size
6564 """
66- low = 2 ** (bit_size - 1 )
65+ low = 2 ** (bit_size - 1 )
6766 high = (2 ** bit_size ) - 1
6867 return sympy .randprime (low , high )
6968
@@ -103,31 +102,33 @@ class Zn:
103102 """
104103 Model of set of Whole numbers less than n.
105104 """
105+
106106 def __init__ (self , n ):
107107 # n :: n = p*q -> p,q are prime
108108 self .n = n
109109
110110 def sample (self ):
111- return random .randint (0 , self .n - 1 )
111+ return random .randint (0 , self .n - 1 )
112112
113- def __contains__ (self , item ): # in operator
113+ def __contains__ (self , item ): # in operator
114114 return (0 <= item ) and (item < self .n )
115115
116116 class Zn_star :
117117 """
118118 Model of set of Natural numbers less than n
119119 which are invertible in (mod n) system.
120120 """
121+
121122 def __init__ (self , n ):
122123 self .n = n
123124
124125 def sample (self ):
125126 while True :
126- temp = random .randint (1 , self .n - 1 )
127+ temp = random .randint (1 , self .n - 1 )
127128 if Utils .GCD (temp , self .n ) == 1 :
128129 return temp
129130
130- def __contains__ (self , item ): # in operator
131+ def __contains__ (self , item ): # in operator
131132 if (1 <= item ) and (item < self .n ):
132133 if Utils .GCD (item , self .n ) == 1 :
133134 return True
@@ -138,6 +139,7 @@ class Zn2_star:
138139 Model of set of Natural numbers less than n^2
139140 which are invertible in (mod n^2) system.
140141 """
142+
141143 def __init__ (self , n ):
142144 # n :: n = p*q -> p,q are prime
143145 self .n2 = n ** 2
@@ -146,16 +148,17 @@ def __init__(self, n):
146148
147149 def sample (self ):
148150 while True :
149- temp = random .randint (1 , self .n2 - 1 )
151+ temp = random .randint (1 , self .n2 - 1 )
150152 if Utils .GCD (temp , self .n2 ) == 1 :
151153 return temp
152154
153- def __contains__ (self , item ): # in operator
155+ def __contains__ (self , item ): # in operator
154156 if (1 <= item ) and (item < self .n2 ):
155157 if Utils .GCD (item , self .n2 ) == 1 :
156158 return True
157159 return False
158160
161+
159162class PaillierCryptosystem :
160163 def __init__ (self , bit_size = 256 ):
161164 self .bitSize = bit_size
@@ -186,25 +189,27 @@ def keyGen(self):
186189 break
187190 self .p = p
188191 self .q = q
189- self .n = p * q
192+ self .n = p * q
190193 self .n2 = self .n ** 2
191- self .g = self .n + 1
192- self .l = (p - 1 ) * ( q - 1 )
193- self .lcm = Utils .LCM ( ( p - 1 ), (q - 1 ) )
194+ self .g = self .n + 1
195+ self .l = (p - 1 ) * ( q - 1 )
196+ self .lcm = Utils .LCM (( p - 1 ), (q - 1 ) )
194197
195- self .mu = Utils .getInverse ( self .lcm , self .n ) # mu = lambda^(-1) (mod n) -->> TRAPDOOR
198+ self .mu = Utils .getInverse (
199+ self .lcm , self .n
200+ ) # mu = lambda^(-1) (mod n) -->> TRAPDOOR
196201
197202 self .publicKey = {
198- "n" : self .n , # Main PUBLIC KEY
199- "n2" : self .n2 , # Defining System - Computational Ease
200- "g" : self .g , # Main PUBLIC KEY
203+ "n" : self .n , # Main PUBLIC KEY
204+ "n2" : self .n2 , # Defining System - Computational Ease
205+ "g" : self .g , # Main PUBLIC KEY
201206 }
202-
207+
203208 self .privateKey = {
204- 'n' : self .n , # Defining System - Computational Ease - Available from PUBLIC KEY
205- 'n2' : self .n2 , # Defining System - Computational Ease - Available from PUBLIC KEY
206- "mu" : self .mu , # Main PRIVATE KEY
207- ' lambda' : self .lcm # Main PRIVATE KEY
209+ "n" : self .n , # Defining System - Computational Ease - Available from PUBLIC KEY
210+ "n2" : self .n2 , # Defining System - Computational Ease - Available from PUBLIC KEY
211+ "mu" : self .mu , # Main PRIVATE KEY
212+ " lambda" : self .lcm , # Main PRIVATE KEY
208213 }
209214
210215 def getPublicKey (self ):
@@ -219,7 +224,7 @@ def getPrivateKey(self):
219224 """
220225 return self .privateKey
221226
222- def encrypt (pubKey : dict , msg : int ):
227+ def encrypt (pubKey : dict , msg : int ):
223228 """
224229 Function to encrypt message using PRIVATE KEY.
225230
@@ -232,8 +237,8 @@ def encrypt(pubKey : dict, msg : int):
232237 n2 = pubKey ["n2" ]
233238 g = pubKey ["g" ]
234239
235- zn = Utils .Zn ( n )
236- zn_star = Utils .Zn_star ( n )
240+ zn = Utils .Zn (n )
241+ zn_star = Utils .Zn_star (n )
237242
238243 # c = (g**x)(r**n) (mod n^2)
239244 assert msg in zn
@@ -242,9 +247,9 @@ def encrypt(pubKey : dict, msg : int):
242247
243248 a = pow (g , msg , n2 )
244249 b = pow (r , n , n2 )
245- return (a * b ) % n2
250+ return (a * b ) % n2
246251
247- def decrypt (prvKey : dict , cypher : int ):
252+ def decrypt (prvKey : dict , cypher : int ):
248253 """
249254 Function to decrypt cypher using PRIVATE KEY.
250255
@@ -254,73 +259,76 @@ def decrypt(prvKey : dict, cypher : int):
254259 cypher belongs to Z(n^2) (all Naturals which are
255260 invertible in (mod n^2) system)
256261 """
257- n = prvKey ['n' ]
258- n2 = prvKey ['n2' ]
259- mu = prvKey ['mu' ]
260- lmbda = prvKey [' lambda' ]
261-
262+ n = prvKey ["n" ]
263+ n2 = prvKey ["n2" ]
264+ mu = prvKey ["mu" ]
265+ lmbda = prvKey [" lambda" ]
266+
262267 t = pow (cypher , lmbda , n2 )
263- t = ( Utils .L (t , n ) ) # L(cypher ^ lambda) == lambda * message (mod n)
268+ t = Utils .L (t , n ) # L(cypher ^ lambda) == lambda * message (mod n)
264269
265- msg = (t * mu ) % n # (lambda * message) * mu == (lambda * message) * (lambda^-1) == msg (mod n)
270+ msg = (
271+ (t * mu ) % n
272+ ) # (lambda * message) * mu == (lambda * message) * (lambda^-1) == msg (mod n)
266273 return msg
267274
268- def homomorphicADD (pubKey : dict , cypher1 : int , cypher2 : int ):
275+ def homomorphicADD (pubKey : dict , cypher1 : int , cypher2 : int ):
269276 """
270277 cypher1 * cypher2 -->> Encryption( msg1 + msg2 )
271278 Both the messages are encrypted and do not
272279 require decryption to perform Binary Operation (ADD)
273-
280+
274281 E(m1) = (g^m1)*(r1^n) (mod n^2)
275282 E(m2) = (g*m2)*(r2^n) (mod n^2)
276-
283+
277284 E(m1+m2) = E(m1)*E(m2) = (g^(m1+m2))*((r1*r2)^n) (mod n^2)
278285 """
279- n2 = pubKey ['n2' ]
280- return (cypher1 * cypher2 ) % n2
286+ n2 = pubKey ["n2" ]
287+ return (cypher1 * cypher2 ) % n2
281288
282- def homomorphicMUL (pubKey : dict , cypher1 : int , msg2 : int ):
289+ def homomorphicMUL (pubKey : dict , cypher1 : int , msg2 : int ):
283290 """
284291 cypher1 ** msg2 -->> Encryption( msg1 * msg2 )
285292 It requires 2nd msg to be decrypted to perfrom
286293 Binary Operation (MUL).
287-
294+
288295 E(m1) = (g^m1)*(r1^n) (mod n^2)
289296 m2 in Zn
290-
297+
291298 E(m1*m2) = E(m1)^m2 (mod n^2)
292299 """
293- n2 = pubKey ['n2' ]
300+ n2 = pubKey ["n2" ]
294301 return pow (cypher1 , msg2 , n2 )
295302
296- if __name__ == '__main__' :
303+
304+ if __name__ == "__main__" :
297305 # base = 256
298306 for i in range (5 , 9 ):
299307 base = 2 ** i
300308 print (f"TESTING BITSIZE : { base } " )
301309 crypto = PaillierCryptosystem (base )
302310 crypto .keyGen ()
303-
311+
304312 pub = crypto .getPublicKey ()
305313 msg = 233
306314 print (f"Msg : { msg } " )
307315 c = PaillierCryptosystem .encrypt (pub , msg )
308- print (f' Cypher : { c } ' )
316+ print (f" Cypher : { c } " )
309317
310318 prv = crypto .getPrivateKey ()
311319 d = PaillierCryptosystem .decrypt (prv , c )
312- print (f' Decryption: { d } ' )
320+ print (f" Decryption: { d } " )
313321 assert msg == d
314-
322+
315323 msg2 = 232
316324 c2 = PaillierCryptosystem .encrypt (pub , msg2 )
317325 c3 = PaillierCryptosystem .homomorphicADD (pub , c , c2 )
318326 d3 = PaillierCryptosystem .decrypt (prv , c3 )
319- assert d3 == (msg + msg2 )
327+ assert d3 == (msg + msg2 )
320328 print ("Homomorphic Add SUCCESSFUL" )
321329
322330 c4 = PaillierCryptosystem .homomorphicMUL (pub , c , msg2 )
323331 d4 = PaillierCryptosystem .decrypt (prv , c4 )
324- assert d4 == (msg * msg2 )
332+ assert d4 == (msg * msg2 )
325333 print ("Homomorphic Mul SUCCESSFUL" )
326- print ()
334+ print ()
0 commit comments