Python Paillier算法 练习
前言
无聊写了一下,可能还是有问题,大家有想法可以加我微信,一起交流。
代码如下(示例):
import gmpy2
import random
import libnum
import math
def gen_prime(n):
"""return a random n-bit prime number 返回一个指定位数的素数
"""
r = gmpy2.mpz(random.SystemRandom().getrandbits(n))
r = gmpy2.bit_set(r, n - 1)
return int(gmpy2.next_prime(r))
def computeLcm(x,y):
if (x > y):
greater = x
else:
greater = y
while(True):
if((greater%x == 0) & (greater%y == 0)):
lcm = greater
break
greater += 1
return lcm
def genetate_random(a, b): #在a,b范围内生成一个随机数函数
while True:
r = random.randint(a, b) #生成一个随机整数
if math.gcd(r, b) == 1: #r与 b 互素
break
return r
class Paillier(object):
def __init__(self,pubkey=None,prikey=None):
self.pubkey=pubkey
self.prikey=prikey
#定义L=(x - 1) / n公式
def L_gongshi(self, x, n):
res = gmpy2.div((x - 1), n)
return res
def key_gen(self):
while True:
l=12
p = gen_prime(int(l))
q = gen_prime(int(l))
n = p * q
lamuda = computeLcm(p-1,q-1)
if gmpy2.gcd(n, lamuda) == 1:
break
g = n + 1
u = gmpy2.invert(lamuda, n)
self.pubKey = [n, g]
self.priKey = [lamuda, u]
return
def encipher(self, plaintext):
m = libnum.s2n(plaintext)
print("mingwen:",m)
n, g = self.pubKey
r=genetate_random(1,n)
ciphertext = gmpy2.powmod(g, m, n ** 2) * gmpy2.powmod(r, n, n ** 2) % (n ** 2)
return ciphertext
def decipher(self, ciphertext):
n, g = self.pubKey
lamuda, u = self.priKey
m = self.L_gongshi(gmpy2.powmod(ciphertext, lamuda, n ** 2), n) * u % n
print("jiemi text:", m)
plaintext1 = libnum.n2s(int(m))
return plaintext1
if __name__ == "__main__":
Paillier = Paillier()
Paillier.key_gen()
pubKey = Paillier.pubKey
plaintext = "niy"
print("mingwen text:", plaintext)
ciphertext = Paillier.encipher(plaintext)
print("Ciphertext:", ciphertext)
deciphertext = Paillier.decipher(ciphertext)
print("Deciphertext: ", deciphertext)
总结
因为素数的位数为12,所以只能加解密三位字符。加我微信:zhongji_me 进交流群一起交流。