1、二次剩餘問題
對於整數n ,定義 。當存在 ,使得 ,稱 a 爲模 n 的二次剩餘;否則稱 a 爲模 n的二次非剩餘。判斷 a 是否爲模 n 的二次剩餘的問題稱爲模n 的二次剩餘問題。
2、Goldwasser-Micali 公鑰加密系統
密鑰產生:
- 大素數 ,求出
- 任取R,滿足
加密:
- 將明文轉化爲二進制數字
- 對於每一個,都對應選取一個
若
若 - 將這個發給
解密:
性質:
a)異或同態性。設明文和 的密文爲和 , 則是 的密文,即 ;
這裏密文相乘之後,需要模p*q,要不然只能實現或同態
b)非運算同態性。即 ;
c)重複加密隨機性。即 。
3、仿真實驗
# GM(Goldwasser - Micali)概率公鑰加密算法,
# 其基於二次剩餘難以複合困難性問題
# GM(Goldwasser - Micali)概率公鑰加密算法,
# 其基於二次剩餘難以複合困難性問題
import math
import random
class Alice:
p = 0
q = 0
N = 0
R = 0
M = []
def __init__(self, p, q, R):
self.p = p
self.q = q
self.N = p * q
self.R = R
# 解密
def Dc(self, eM):
self.M = []
for i,em in enumerate(eM):
temp = '0'
c = int(math.sqrt(em % self.N))
# a = int(math.sqrt(em % self.q))
# 判斷加密後的數組元素a, (a mod p) and (a mod q)是否是二次剩餘
if c ** 2 == em:
temp = '0'
# if c ** 2 != em and a ** 2 != em:
else:
temp = '1'
self.M.append(temp)
return self.M
class Bob:
M = ''
PK = {
"R" : 0,
"N" : 0
}
C = []
def __init__(self, R, N):
self.PK['R'] = R
self.PK['N'] = N
# 加密
def Ec(self, M):
C = []
for i,m in enumerate(M):
c = 0
# 產生一個隨機數,要滿足randomnum是mod N的二次剩餘
randomnum = random.randint(1,20000)
if m == '1':
c = (self.PK['R'] * (randomnum ** 2) ) % self.PK["N"]
else:
c = (randomnum ** 2) % self.PK["N"]
C.append(c)
return C
# 驗證同態性質
def testTong(a, b, n):
result = []
for i in range(len(a)):
result.append((a[i] * b[i]) % n)
return result
if __name__ == '__main__':
p, q, R = 232312311797, 971179711797, 17
a = "1011011000111110000110" #
b = "0011011000101110000111" #
alice = Alice(p, q, R)
bob = Bob(R, p * q)
aa = bob.Ec(a)
alice.Dc(aa)
bb = bob.Ec(b)
print("aa: "+ str(aa))
print("bb: "+ str(bb))
print("Dc(aa): "+ str(alice.Dc(aa)))
print("Dc(bb): "+ str(alice.Dc(bb)))
#驗證加密後的數據是否具有異或同態性質
temp = testTong(aa, bb, p * q)
print("temp: "+ str(temp))
print("Dc(temp): "+ str(alice.Dc(temp)))
aa: [1332385353, 316626436, 130910625, 3285042617, 28761769, 2155772057, 1336602713, 16999129, 251381025, 25553025, 1390189433, 88128, 1025018825, 2584072097, 2034621200, 123298816, 712336, 128074489, 301925376, 90321425, 3037049252, 215355625]
bb: [86899684, 48011041, 6395481872, 3666536132, 213861376, 3628548, 4747377857, 110229001, 136282276, 38675961, 352512, 125821089, 105486377, 2007928208, 110282553, 101787921, 52243984, 8543929, 27071209, 4034338425, 864954713, 677517473]
Dc(aa): ['1', '0', '1', '1', '0', '1', '1', '0', '0', '0', '1', '1', '1', '1', '1', '0', '0', '0', '0', '1', '1', '0']
Dc(bb): ['0', '0', '1', '1', '0', '1', '1', '0', '0', '0', '1', '0', '1', '1', '1', '0', '0', '0', '0', '1', '1', '1']
temp: [115783866141928452, 15201564800479876, 837236529039690000, 12044727450390337444, 6151031494534144, 7822322385883236, 6345358123302326041, 1873797007540129, 34258778230212900, 988287798332025, 490058457405696, 11088360931392, 108125522206047025, 5188631255072012176, 224383220323923600, 12550330142401536, 37215270586624, 1094259340727281, 8173484956099584, 364387195478255625, 2626910064130524676, 145907198846335625]
Dc(temp): ['1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1']
最後的結果加解密能夠正常運行,同時此加密算法的異或同態也正確,temp中存放就是抑或之後的密文
本人才疏學淺,如有紕漏,歡迎指正,謝謝!